android Cursor的自動管理方式

來源:互聯網
上載者:User

標籤:

  新手在使用資料庫的時候,很容易忘記關閉Cursor,造成嚴重記憶體流失。有什麼好的方法解決這個問題呢?除了自己管理Cursor,有什麼辦法把Cursor交給系統管理,而不需要自己主動close呢?manageQuery可以為你維護這個cursor。在你退出activity時為你自動關閉。

  The method managedQuery(Uri, String[], String, String[], String) from the type Activity is deprecated。

android官方文檔推薦用CursorLoader類來取代。

  我們先來分析一下manageQuery是如何管理cursror的

 private static final class ManagedCursor {        ManagedCursor(Cursor cursor) {            mCursor = cursor;            mReleased = false;            mUpdated = false;        }        private final Cursor mCursor;        private boolean mReleased;        private boolean mUpdated;    }    private final ArrayList<ManagedCursor> mManagedCursors =        new ArrayList<ManagedCursor>();

   public final Cursor managedQuery(Uri uri, String[] projection, String selection,            String[] selectionArgs, String sortOrder) {        Cursor c = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);        if (c != null) {            startManagingCursor(c);        }        return c;    }
    public void startManagingCursor(Cursor c) {        synchronized (mManagedCursors) {            mManagedCursors.add(new ManagedCursor(c));        }    }
  protected void onDestroy() {        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);        mCalled = true;        // dismiss any dialogs we are managing.        if (mManagedDialogs != null) {            final int numDialogs = mManagedDialogs.size();            for (int i = 0; i < numDialogs; i++) {                final ManagedDialog md = mManagedDialogs.valueAt(i);                if (md.mDialog.isShowing()) {                    md.mDialog.dismiss();                }            }            mManagedDialogs = null;        }        // close any cursors we are managing.        synchronized (mManagedCursors) {            int numCursors = mManagedCursors.size();            for (int i = 0; i < numCursors; i++) {                ManagedCursor c = mManagedCursors.get(i);                if (c != null) {                    c.mCursor.close();                }            }            mManagedCursors.clear();        }        // Close any open search dialog        if (mSearchManager != null) {            mSearchManager.stopSearch();        }        getApplication().dispatchActivityDestroyed(this);    }

  看來這幾個方法就已經非常明確了。將cursor封裝之後放到一個ArrayList中,在Activity的Destroy方法中關閉cursor,Activity正常銷毀一定會走OnDestroy()方法的,這樣可以保證cursor會被關閉。
LoaderManager方法有下面幾個方面更勝一籌:
1. startManagingCursor管理Cursors,而LoaderManager管理Loader<D>對象。Loader<D>是一個模板類,D是一個包含了需要載入資料的類。也就是說,資料來源並不必須是Cursor,它可以是List、JSONArray。。。任何類。LoaderManager與它包含的資料內容解耦了,所以更加靈活。
2. 調用startManagingCursor會導致Activity在已經加入管理的Cursor上調用requery()方法。在第一篇文章中提到過,在UI線程執行requery()方法代價非常高。相反的是,Loader<D>的子類會非同步載入(譯者註:另外再開一個線程,就叫非同步了。)資料,所以使用LoaderManager永遠不會產生阻塞UI線程的情況。
3. startManagingCursor在配置變化(例如橫豎屏切換)時,並不會保持Cursor的狀態。麻煩的是,每次Activity由於配置變化(比如,簡單的橫豎屏切換),都會導致Cursor下回並且被重新查詢。LoaderManager就智能多了,當配置變化時,它會保持它裡面的Loader們的狀態,所以並不需要重新查詢資料。
4. LoaderManager提供無縫的資料監測。任何時候,當Loader的資料來源改變,LoaderManager將會從對應的Loader上面接收到一個新的同步載入資料,並將更新資料返回給用戶端(注意:僅當Loader被正確實現,LoaderManager才會接收到這些資料變化通知。我們將會在該系列的第三篇文章討論自訂Loaders的實現)。

  CursorLoader使用LoaderManager管理Cursor

使用方法如下

LoaderCallbacks<Cursor> callback= new  LoaderCallbacks<Cursor>() {               @Override               public Loader<Cursor> onCreateLoader(int id, Bundle args) {                      // 返回自己需要的CursorLoader                      return null ;              }               @Override               public void onLoadFinished(Loader<Cursor> loader, Cursor data) {                      // 使用swapCursor()方法,以使舊的遊標不被關閉.                      simpleCursorAdapter.swapCursor(cursor);              }               @Override               public void onLoaderReset(Loader<Cursor> loader) {       、                       // 一般寫這樣寫                       simpleCursorAdapter.swapCursor(null);              } }; getLoaderManager().initLoader(0, null, callback);


需要注意的是當使用initLoader()時,如果指定ID的裝載器已經存在,則它使用這個裝載器.如果不存在呢,它將建立一個新的.但是有時你卻是想丟棄舊的然後開始新的資料,要使用restartLoader()方法。


歡迎掃描二維碼,關注公眾號






android Cursor的自動管理方式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.