日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

cursor管理

發布時間:2023/11/29 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 cursor管理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  使用cursor的時候需要注意在使用完之后將其關閉,什么時候關閉也是一個需要注意的問題,稍不小心就可能會出錯。我們自己管理cursor可能不是那么容易,問題出現這個或那樣的問題,Android系統提供了一套curosr的管理,下面讓我們來了解一下。

managedQueryquery的區別

  我們都知道在Android系統中,SQLite數據庫的相關操作方式被封裝為內容提供 Content Provider,可以幫助那些不會SQL語言的開發者快速實現Android平臺上的數據庫操作,但是平時我們在查詢時一般返回的是Cursor對象,從本質上來看這兩個API是不同的類提供的。比如 ContentResolver.query(),以及 Activity.managedQuery()所以,我們看到一個是ContentResolver提供的查詢方法,位于android.content.ContextWrapper.getContentResolver(),另一個則為Activity。

  這兩種方法的參數是一樣的,但是Activity類的方法在整個生命周期中受Activity的影響,而常規我們處理數據邏輯可能單獨分成一個類,直接使用Context對象傳遞實例句柄,對于數據庫查詢操作如果數據較為龐大盡量使用異步的 AsyncQueryHandler方法防止阻塞線程。

  Activity 里面提供了一個 managedQuery() 方法,按照 Android SDK 里面的說明,“the activity will manage its lifecycle for you.” 聽起來很好,Activity 可以替你管理 Cursor 的生命周期了,就不用記著去 close() 了,代碼可以更簡潔。

  但是 Activity 是怎么去管理 Cursor 的生命周期的呢?SDK 文檔沒說。最近遇到一個 bug,在一個 Activity 中,用 managedQuery() 查詢數據庫,將查詢得到的 Cursor 用 CursorAdapter 與 ListView 綁定。然后在 Activity 里面執行批量刪除數據表記錄操作,因為耗時比較長,所以用了多線程處理。測試團隊發現的 bug 是,在刪除操作進行過程中,如果按下 Home 鍵,應用就崩潰了。崩潰原因是 Cursor 被釋放了,導致工作線程的刪除操作異常。

  看了 Activity.java 的源碼之后就明白為什么會崩潰了。managedQuery() 其實無非就是把查詢得到的 Cursor 放到了 Activity 類的一個數組成員變量mManagedCursors中,然后當 Activity stop 的時候,將這個數組里的每個 cursor 都調用mCursor.deactivate();使curosr無效,直到下次再調用requery()方法,以及在 restart()的時候,將數組里的每個 cursor 都重新查詢一次。所以在按下 Home 鍵之后,Activity 調用了 OnStop 了,cursor 也就無效了,如果有個線程還在繼續使用這個 cursor,就會拋異常了。

  因此,在用 managedQuery() 的時候,需要清楚 cursor 什么時候會被釋放,并考慮好自己的代碼在 cursor 被釋放后不再需要使用這個 cursor.

  可以用普通的query,然后運行 startManagingCursor(cursor),同樣可以把cursor交給系統去管理,不用擔心cursor沒有close的情況了。?

?

使用CurosrLoader管理cursor

  Android 3.0引入了CursorLoader實現異步加載數據,為了避免同步查詢數據庫時阻塞UI線程的問題。在API 11之前可以通過下載支持庫,來使之前的系統支持此功能.

  在Android 3.0之后,官方推薦使用CursorLoader來對curosr進行管理,如果想在3.0之前的版本使用,需要繼承FragmentActivity,該類位于android-support-v4.jar包中,直接使用FragmentActivity會報錯,需要導入該包(該包位于F:\android-sdk\extras\android\support)。

  相信不少人都知道Android compatibility這個兼容包的存在。是的,Android compatibility包里面就有FragmentActivity和Fragment這套東西。它有兩個版本v4和v13,其中v4就支持支持從android sdk1.6開始,可以使用Fragment。Android compatibility包是一個靜態的jar包,我們只需要將它置于工程中,導入進工程,就能很方便的引用到FragmentActivity和Fragment了。

下面的代碼展示了在Android 3.0之前使用Loader的用法:

import android.os.Bundle;

import android.support.v4.app.FragmentActivity;

import android.support.v4.app.LoaderManager;

import android.support.v4.content.Loader;

import android.widget.Toast;

?

public class MyActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<Object> {

public void onCreate(Bundle savedInstanceState) {

? ? super.onCreate(savedInstanceState);

? ? setContentView(R.layout.main);

? ? getSupportLoaderManager().initLoader(0, null, this);

}

?

public Loader<Object> onCreateLoader(int i, Bundle bundle){

? ? return null; // TODO

}

?

public void onLoadFinished(Loader loader, Object o) {

? ? Toast.makeText(this, "onLoadFinished", Toast.LENGTH_SHORT).show();

}

?

public void onLoaderReset(Loader loader) ? ?{

? ? Toast.makeText(this, "onLoaderReset", Toast.LENGTH_SHORT).show();

}

}

?

?

Loaders,中文可理解為“加載器”,在Android3.0中新增。從字面含義可見其功能,即提供數據加載。特別地,加載數據的方式為異步。它具有以下特點:

l??Loaders用于所有的Activity和Fragment;

l??提供異步數據裝載機制;

l??監控他們的來源數據變化情況,在數據發生變化的時候傳遞新的結果;

l??自動重連到最后一個數據加載器游標,因此不需要重新查詢數據

如何在應用中使用Loaders

使用Loaders的先決條件:

l??需要一個Activity?或者?Fragmnet

l??一個LoaderManager實例

l??一個用于加載數據的的CursorLoader對象(依賴于ContentProvider)

l??一個LoaderManager.LoaderCallbacks的實現類.

l??一個數據展現適配器,比如SimpleCursorAdapter

l??一個數據源,比如ContentProvider

啟動數據加載器Loaders

LoaderManager管理者一個Activity或者Fragment中的一個或多個Loader實例,每個Activity或者Fragment只有對應一個LoaserManager。

?????????一般在Activity的onCreate方法或者Fragment的onActivityCreated方法中初始化一個Loader:

getLoaderManager().initLoader(0, null, this);

參數:

1、??第一個參數:0?為Loader的唯一標識ID;

2、??第二個參數:?為Loader的構造器可選參數,這里為null;

3、??第三個參數:this,這里表示當前Activity對象或者Fragment對象,提供給LoaderManager對象進行數據匯報。

InitLoader()方法保證了Loader初始化及對象激活,執行這個方法有2個可能的結果:

1、??如果ID存在,則重復利用;

2、??如果ID不存在,則出發LoaderManager.LoaderCallbacks的onCreateLoader()方法新創建一個Loader并返回;

?

不管在什么情況下,只有Loader狀態發生了變化,與之關聯的LoaderManager.LoaderCallbacks實現類都會被告知;

  你可能注意到了,initLoader返回的Loader對象并未與任何變量關聯,那是因為LoaderManager有自動的Loader管理功能;LoaderManager在必要的時候自動啟動及停止數據加載操作,并且維護者Loader的狀態;這就意味著,你很少直接與Loader進行交互。一般地,使用LoaderManager.LoaderCallbacks的onCreateLoader()方法去干預數據加載的過程中的特殊事件。

如何重啟數據加載器Loaders

  在上面創建Loaders時,如果ID不存在則創建,否則使用舊的Loader,但有些時候,我們需要清理掉舊的數據重新開始。

  使用restartLoaser()可以做到。比如,SearchView.OnQueryTextListener的實現類,在查詢條件發生改變時重啟Loaders,以便獲取最新的查詢結果。

public boolean onQueryTextChanged(String newText) {

????// Called when the action bar search text has changed.??Update

????// the search filter, and restart the loader to do a new query

????// with this filter.

????mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;

????getLoaderManager().restartLoader(0, null, this);

????return true;}

如何使用LoaderManager的回調方法

  LoaderManager.LoaderCallbacks?接口是客戶端與LoaderManager進行交互的腰帶。

  Loader?,特別是CursorLoader,期望在停止狀態后保存它們的狀態。這樣的話,用戶在交互過程中,就避免了數據的重新加載而導致UI卡死的局面。使用回調函數,就可以知道什么時候去創建一個新的Loader,并且告知應用程序什么時候停止使用Loader加載的數據。

回調方法有:

l??onCreateLoader():根據給定的ID創建新的Loader;

l??onLoaderFinished():當Loader完成數據加載后調用;

l??onLoaderReset():Loader重置,使之前的數據無效;

?

onCreateLoader使用實例:

// If non-null, this is the current filter the user has provided.

String mCurFilter;

...

public Loader<Cursor> onCreateLoader(int id, Bundle args) {

????// This is called when a new Loader needs to be created. ?This

????// sample only has one Loader, so we don't care about the ID.

????// First, pick the base URI to use depending on whether we are

????// currently filtering.

????Uri baseUri;

? ? if (mCurFilter != null) {

? ? ? ? baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,

? ? ? ? ? ? ? ????Uri.encode(mCurFilter));

? ? } else {

? ? ? ? baseUri = Contacts.CONTENT_URI;

? ? }

?

? ? // Now create and return a CursorLoader that will take care of

? ? // creating a Cursor for the data being displayed.

? ? String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("

? ? ? ? ? ? + Contacts.HAS_PHONE_NUMBER + "=1) AND ("

? ? ? ? ? ? + Contacts.DISPLAY_NAME + " != '' ))";

? ? return new CursorLoader(getActivity(), baseUri,

? ? ? ? ? ? CONTACTS_SUMMARY_PROJECTION, select, null,

? ? ? ? ? ? Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");}

CursorLoader(Context?context,?Uri?uri,?String[]?projection,?String?selection,?String[]?selectionArgs,?String?sortOrder)構造器參數解釋:

Context:上下文,這里是Activity對象或者Fragment對象

Uri:內容檢索地址

Projection:要顯示的列,傳null表示查詢所有的列

Selection:查詢過濾語句,類似SQL WHERE?,傳null,表示查詢所有

selectionArgs:查詢參數,替換在selection中定義的???

sortOrder:排序定義,類似SQL ORDER BY

完整的實例

public static class CursorLoaderListFragment extends ListFragment

? ? ? ? implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> {

?

????// This is the Adapter being used to display the list's data.

? ? SimpleCursorAdapter mAdapter;

?

? ? // If non-null, this is the current filter the user has provided.

? ? String mCurFilter;

?

? ? @Override public void onActivityCreated(Bundle savedInstanceState) {

? ? ? ? super.onActivityCreated(savedInstanceState);

?

? ? ? ? // Give some text to display if there is no data. ?In a real

? ? ? ? // application this would come from a resource.

? ? ? ? setEmptyText("No phone numbers");

?

? ? ? ? // We have a menu item to show in action bar.

? ? ? ? setHasOptionsMenu(true);

?

? ? ? ? // Create an empty adapter we will use to display the loaded data.

? ? ? ? mAdapter = new SimpleCursorAdapter(getActivity(),

? ? ? ? ? ? ? ? android.R.layout.simple_list_item_2, null,

? ? ? ? ? ? ? ? new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },

? ? ? ? ? ? ? ? new int[] { android.R.id.text1, android.R.id.text2 }, 0);

? ? ? ? setListAdapter(mAdapter);

?

? ? ? ? // Prepare the loader. ?Either re-connect with an existing one,

? ? ? ? // or start a new one.

? ? ? ? getLoaderManager().initLoader(0, null, this);

? ? }

?

? ? @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

? ? ? ? // Place an action bar item for searching.

? ? ? ? MenuItem item = menu.add("Search");

? ? ? ? item.setIcon(android.R.drawable.ic_menu_search);

? ? ? ? item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

? ? ? ? SearchView sv = new SearchView(getActivity());

? ? ? ? sv.setOnQueryTextListener(this);

? ? ? ? item.setActionView(sv);

? ? }

?

? ? public boolean onQueryTextChange(String newText) {

? ? ? ? // Called when the action bar search text has changed. ?Update

? ? ? ? // the search filter, and restart the loader to do a new query

? ? ? ? // with this filter.

? ? ? ? mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;

? ? ? ? getLoaderManager().restartLoader(0, null, this);

? ? ? ? return true;

? ? }

?

? ? @Override public boolean onQueryTextSubmit(String query) {

? ? ? ? // Don't care about this.

? ? ? ? return true;

? ? }

?

? ? @Override public void onListItemClick(ListView l, View v, int position, long id) {

? ? ? ? // Insert desired behavior here.

? ? ? ? Log.i("FragmentComplexList", "Item clicked: " + id);

? ? }

?

? ? // These are the Contacts rows that we will retrieve.

? ? static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {

? ? ? ? Contacts._ID,

? ? ? ? Contacts.DISPLAY_NAME,

? ? ? ? Contacts.CONTACT_STATUS,

? ? ? ? Contacts.CONTACT_PRESENCE,

? ? ? ? Contacts.PHOTO_ID,

? ? ? ? Contacts.LOOKUP_KEY,

? ? };

? ? public Loader<Cursor> onCreateLoader(int id, Bundle args) {

? ? ? ? // This is called when a new Loader needs to be created. ?This

? ? ? ? // sample only has one Loader, so we don't care about the ID.

? ? ? ? // First, pick the base URI to use depending on whether we are

? ? ? ? // currently filtering.

? ? ? ? Uri baseUri;

? ? ? ? if (mCurFilter != null) {

? ? ? ? ? ? baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,

? ? ? ? ? ? ? ? ? ? Uri.encode(mCurFilter));

? ? ? ? } else {

? ? ? ? ? ? baseUri = Contacts.CONTENT_URI;

? ? ? ? }

?

? ? ? ? // Now create and return a CursorLoader that will take care of

? ? ? ? // creating a Cursor for the data being displayed.

? ? ? ? String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("

? ? ? ? ? ? ? ? + Contacts.HAS_PHONE_NUMBER + "=1) AND ("

? ? ? ? ? ? ? ? + Contacts.DISPLAY_NAME + " != '' ))";

? ? ? ? return new CursorLoader(getActivity(), baseUri,

? ? ? ? ? ? ? ? CONTACTS_SUMMARY_PROJECTION, select, null,

? ? ? ? ? ? ? ? Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");

? ? }

?

? ? public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

? ? ? ? // Swap the new cursor in. ?(The framework will take care of closing the

? ? ? ? // old cursor once we return.)

? ? ? ? mAdapter.swapCursor(data);

? ? }

?

? ? public void onLoaderReset(Loader<Cursor> loader) {

? ? ? ? // This is called when the last Cursor provided to onLoadFinished()

? ? ? ? // above is about to be closed. ?We need to make sure we are no

? ? ? ? // longer using it.

? ? ? ? mAdapter.swapCursor(null);

? ? }}

?

轉載于:https://www.cnblogs.com/adm1989/archive/2013/01/14/2860207.html

總結

以上是生活随笔為你收集整理的cursor管理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 嫩草99| 在线视频网 | 欧美精品卡一卡二 | 啪啪视屏| 双乳被四个男人吃奶h文 | 欧美国产在线一区 | 青青草一区 | 69色综合 | 欧美色拍| 国产高清久久久 | 国产精品综合久久 | 日韩在线观看不卡 | 国产日韩二区 | 国产第9页 | 欧美一区日韩一区 | 亚洲无人区码一码二码三码 | 最新av免费在线观看 | 大奶子av| 很黄的性视频 | 久久婷婷网 | 一区二区成人免费视频 | 一级免费毛片 | 久久影视精品 | 国产日产欧洲无码视频 | 久色网| 日韩视频在线观看一区 | 天天看夜夜爽 | 最新视频–x99av | 日韩成人综合 | 国产国语性生话播放 | 亚洲网友自拍 | 日韩极品少妇 | 一级片免费网站 | 色女综合 | 日本高清不卡在线观看 | 人成精品| 一本av在线 | 国产孕妇一区二区三区 | 99久久精品无免国产免费 | 中文字幕超清在线观看 | 激情婷婷综合网 | 自拍偷拍欧美日韩 | 亚洲欧美激情一区二区三区 | 视频在线播 | 成人精品福利 | 污污视频在线免费看 | 美女屁股眼视频免费 | 国产 xxxx| 亚洲午夜毛片 | 福利在线小视频 | 日本一本在线视频 | 三级在线网址 | 久久1024 | 免费在线看黄的网站 | 黄色av电影网址 | 欧美久久激情 | 色五夜| 区一区二视频 | 久久99精品久久久久 | 欧美 亚洲 视频 | 开心春色激情网 | 无码人妻丰满熟妇奶水区码 | 高h喷水荡肉少妇爽多p视频 | 久久伊人中文字幕 | 蜜臀av中文字幕 | 午夜视频欧美 | 少妇与公做了夜伦理 | 阿v天堂在线 | 成人美女在线观看 | 男同激情视频 | 国产成人在线观看免费网站 | 九九黄色片| 人妻一区二区在线 | 国产处女| 国产精品欧美一区二区三区 | a级一级黄色片 | 欧美人交a欧美精品 | 国产一区二区久久精品 | 九色综合网 | 亚洲色图图片 | 国产亚洲av综合人人澡精品 | 亚洲天堂免费av | 欧美精品第1页 | 欧美精品毛片 | 欧美精品一级二级三级 | 在线精品一区二区 | 天堂在线中文资源 | 美女被捅个不停 | 亚洲国产精品国自产拍久久 | 三上悠亚痴汉电车 | 亚洲色图 美腿丝袜 | 在线观看av毛片 | 尤物精品在线 | 日本免费在线视频观看 | 亚洲在线日韩 | 欧美69囗交视频 | 可以看污的网站 | 在线观看h网站 | 999精彩视频|