LoaderManagerとAsyncTaskLoader<br>詳しく説明する

9220 ワード

LoaderManagerとは何ですか?
簡単な理解では、LoaderManagerはActivityまたはFragmentに関連付けられた1つ以上のLoadersオブジェクトを管理するために使用されます.各ActivityまたはFragmentには、そのLoaderManagerインスタンスを起動、停止、保持、再起動、閉じるための唯一のLoaderManagerインスタンスがあります.これらのイベントは、クライアントがinitLoader()/restartLoader()/destroyLoader()関数を呼び出すことによって直接実現される場合がある.通常、これらのイベントは、手動ではなく、主なActivity/Fragment宣言サイクルイベントによってトリガーされます(もちろん手動で呼び出すこともできます).
LoaderManagerでは、データがどのようにマウントされ、いつマウントされるかはわかりません.逆に、LoaderManagerは、そのLoadersの動作を開始、停止、リセットするだけで、変換(縦横画面切り替えなど)を構成するときにloadersの状態を維持し、load結果をクライアントに取得するための簡単なインタフェースを提供します.
LoaderManagerは、Loadersを初期化、管理、破棄し、コードの複雑さとActivityまたはFragmentのライフサイクルに関連するバグを低減します.さらに、LoaderManagerとのインタラクションには、3つの簡単なコールバック方法が必要です.もちろん、まずLoaderCallbacksを継承します.継承すると、3つのコールバックメソッドが自動的に追加されます.
  • onCreateLoaderは、新しいLoaderを返すための工場メソッドです.LoaderManagerは、初めてLoaderを作成したときにこのメソッドを呼び出します.
  • onLoadFinishedメソッドは、Loaderの作成が完了すると自動的に呼び出されます.典型的には、データのロードが完了すると、クライアントはアプリケーションUIを更新する必要があります.クライアントは、新しいデータがあるたびに、新しいデータがこのメソッドに返されると仮定します.データソースの検出はLoaderの作業であり、Loaderも実際の同期ロード操作を実行することを覚えておいてください.Loaderのデータのロードが完了すると、LoaderManagerはこれらのロードデータを受け入れ、結果をコールバックオブジェクトのonLoadFinishedメソッドに伝え、クライアント(ActivityやFragmentなど)がデータを使用できるようになります.
  • 最後に、LoaderたちのデータがリセットされるとonLoadResetが呼び出されます.この方法では、既存のデータから不要なデータを削除できます.
  • public class Test extends Activity implements LoaderCallbacks<List<String>>{
    
        // , Loader
        //LoaderManager Loader 。
        // 
        @Override
        public Loader<List<String>> onCreateLoader(int id, Bundle args) {
            return null;
        }
    
        // Loader 
        // , , update  ui 。
        @Override
        public void onLoadFinished(Loader<List<String>> loader, List<String> data) {
    
        }
    
        // 
        @Override
        public void onLoaderReset(Loader<List<String>> loader) {
        }
    }

    Loaders特性
    含む:1.個別のスレッドにデータをロードします.2.下位データ・ソースを監視し、変更が検出された場合に更新または再照会する.
    これらの特性は最終的にLoaderの挙動を決定した.
  • 非同期ロードのタスクを実行します.独立したスレッドでロード操作が実行されるようにするには、Loaderのサブクラスは、LoaderクラスではなくAsyncTaskLoaderを継承する必要があります.AsyncTaskLoaderは抽象Loaderであり、AsyncTaskがその実行操作を提供する.サブクラスを定義すると,抽象法loadInBackground法を実現することによって非同期taskを実現する.このメソッドは、1つのワークスレッドでデータロード操作を実行します.
  • public class TestLoader extends AsyncTaskLoader<List<String>> {
    
        public TestLoader(Context context) {
            super(context);
        }
    
        @Override
        public List<String> loadInBackground() {
            return null;
        }
    
        protected void onStartLoading() {
            if(takeContentChanged()){// 
                forceLoad();
            }
        };
    }
  • は、登録リスナーにおいて、ロード完了の結果を受信する.各Loaderについて、LoaderManagerは、onLoadFinished(Loader loader,D result)メソッドを呼び出すことによってLoaderに結果をクライアントに送信するOnLoadCompleteListenerを登録します.LoaderはLoader#deliverResult(D result)を呼び出すことで、登録されたリスナーたちに結果を渡します.ソース:
  •     public interface OnLoadCompleteListener<D> {
            /**
             * Called on the thread that created the Loader when the load is complete.
             *
             * @param loader the loader that completed the load
             * @param data the result of the load
             */
            public void onLoadComplete(Loader<D> loader, D data);
        }
            @Override
            public void onLoadComplete(Loader<Object> loader, Object data) {
                ......
                // Notify of the new data so the app can switch out the old data before
                // we try to destroy it.
                if (mData != data || !mHaveData) {
                    mData = data;
                    mHaveData = true;
                    if (mStarted) {
                        callOnLoadFinished(loader, data);
                    }
                }
                ......
            }
    
            void callOnLoadFinished(Loader<Object> loader, Object data) {
                if (mCallbacks != null) {
                    String lastBecause = null;
                    if (mActivity != null) {
                        lastBecause = mActivity.mFragments.mNoTransactionsBecause;
                        mActivity.mFragments.mNoTransactionsBecause = "onLoadFinished";
                    }
                    try {
                        if (DEBUG) Log.v(TAG, " onLoadFinished in " + loader + ": "
                                + loader.dataToString(data));
                        mCallbacks.onLoadFinished(loader, data);
                        // onLoadFinished
                    } finally {
                        if (mActivity != null) {
                            mActivity.mFragments.mNoTransactionsBecause = lastBecause;
                        }
                    }
                    mDeliveredData = true;
                }
            }

    ソースコードから、インタフェースを継承してonLoadCompleteを実装していることがわかります.この関数でonLoadFinishedを呼び出す
  • データソースの変更の通知を受信する観察者がいる.Loaderは、これらのObserverのうちの1つ(ContentObserver、BroadcastReceiverなど)を実装して、下位データソースの変更を検出する必要があります.データの変更が検出されると、観察者はLoader#onContentChanged()を呼び出さなければならない.この方法では、2つの異なる操作が実行される.a.Loaderがすでに起動状態にある場合、新しいロード操作が実行される.b.flag識別データソースの設定が変更され、Loaderが再起動すると、データを再ロードすべきであることがわかります.

  • 以上の2つの文章を見て、Android開発のContentProviderとLoaderManagerのロードデータ(図文ソースコード共有)Android非同期ロード神器Loaderの全解析をより深く説明します.