LoaderManager源码分析之一

1, 基本概念

LoaderManager从名字来看,就是异步任务的意思。

LoaderManager是一个抽象类定义如下,

public abstract class LoaderManager {

还包含一个接口,有三个方法,

public interface LoaderCallbacks<D> {
        public Loader<D> onCreateLoader(int id, Bundle args);
        public void onLoadFinished(Loader<D> loader, D data);
        public void onLoaderReset(Loader<D> loader);
    }

实际上, 内部类LoaderManagerImpl是LoaderManager的代理类,负责所有方法的执行。

LoaderManager定义如下,

class LoaderManagerImpl extends LoaderManager {

2, LoaderManager使用

源码中Contacts加载联系人就利用了LoaderManager机制,实现也很简单,继承LoaderCallbacks接口并且实现三个方法就可以了。

ContactEntryListFragment中的实现如下,

导入包

import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;

继承LoaderCallbacks接口

implements LoaderCallbacks<Cursor>

实现方法,

onCreateLoader方法

public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        if (id == DIRECTORY_LOADER_ID) {
            •••
        } else {
            CursorLoader loader = createCursorLoader(mContext);
            long directoryId = args != null && args.containsKey(DIRECTORY_ID_ARG_KEY)
                    ? args.getLong(DIRECTORY_ID_ARG_KEY)
                    : Directory.DEFAULT;
            mAdapter.configureLoader(loader, directoryId);
            return loader;
        }
}

public CursorLoader createCursorLoader(Context context) {
        return new CursorLoader(context, null, null, null, null, null) {
            @Override
            protected Cursor onLoadInBackground() {
                try {
                    return super.onLoadInBackground();
                } catch (RuntimeException e) {
                    // We don't even know what the projection should be, so no point trying to
                    // return an empty MatrixCursor with the correct projection here.
                    Log.w(TAG, "RuntimeException while trying to query ContactsProvider.");
                    return null;
                }
            }
        };
    }
onLoadFinished方法如下,使用完成之后,要调用destroyLoader方法。

public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        •••
                mDirectoryListStatus = STATUS_NOT_LOADED;
                getLoaderManager().destroyLoader(DIRECTORY_LOADER_ID);
    }

onLoaderReset是一个空的方法,

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

还需要借助于CursorLoader来实现异步查询。

Activity/Fragment 中的getLoaderManager 最后获取的是LoaderManagerImpl对象。

3, 加载原理

异步加载主要分为以下几个步骤,

3.1, initLoader

调用流程图如下,


LoaderManagerImpl的initLoader方法如下,

Callback指继承LoaderCallbacks接口的类对象。

public <D> Loader<D> initLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<D> callback) {
        if (mCreatingLoader) {
            throw new IllegalStateException("Called while creating a loader");
        }
        
        LoaderInfo info = mLoaders.get(id);
        
        if (DEBUG) Log.v(TAG, "initLoader in " + this + ": args=" + args);

        if (info == null) {
            // Loader doesn't already exist; create.
            info = createAndInstallLoader(id, args,  (LoaderManager.LoaderCallbacks<Object>)callback);
            if (DEBUG) Log.v(TAG, "  Created new loader " + info);
        } else {
            if (DEBUG) Log.v(TAG, "  Re-using existing loader " + info);
            info.mCallbacks = (LoaderManager.LoaderCallbacks<Object>)callback;
        }
        
        if (info.mHaveData && mStarted) {
            // If the loader has already generated its data, report it now.
            info.callOnLoadFinished(info.mLoader, info.mData);
        }
        
        return (Loader<D>)info.mLoader;
    }

createAndInstallLoader代码如下,

private LoaderInfo createAndInstallLoader(int id, Bundle args,
            LoaderManager.LoaderCallbacks<Object> callback) {
        try {
            mCreatingLoader = true;
            LoaderInfo info = createLoader(id, args, callback); // 构造LoaderInfo对象
            installLoader(info); // 对LoaderInfo进行初始化
            return info;
        } finally {
            mCreatingLoader = false;
        }
    }

createLoader首先构造一个内部类LoaderInfo对象,然后回调ContactEntryListFragment的onCreateLoader方法创建Loader对象,

实际上是CursorLoader对象。最后将CursorLoader对象作为LoaderInfo对象的mLoader变量。

private LoaderInfo createLoader(int id, Bundle args,
            LoaderManager.LoaderCallbacks<Object> callback) {
        LoaderInfo info = new LoaderInfo(id, args,  (LoaderManager.LoaderCallbacks<Object>)callback);
        Loader<Object> loader = callback.onCreateLoader(id, args);
        info.mLoader = (Loader<Object>)loader;
        return info;
    }

LoaderInfo类似于一个中间人的角色。

void installLoader(LoaderInfo info) {
        mLoaders.put(info.mId, info);
        if (mStarted) {
            // The activity will start all existing loaders in it's onStart(),
            // so only start them here if we're past that point of the activitiy's
            // life cycle
            info.start();
        }
    }

LoaderInfo的start方法如下,

void start() {
            if (mRetaining && mRetainingStarted) {
                // Our owner is started, but we were being retained from a
                // previous instance in the started state...  so there is really
                // nothing to do here, since the loaders are still started.
                mStarted = true;
                return;
            }

            if (mStarted) {
                // If loader already started, don't restart.
                return;
            }

            mStarted = true;
            
            if (DEBUG) Log.v(TAG, "  Starting: " + this);
            if (mLoader == null && mCallbacks != null) {
               mLoader = mCallbacks.onCreateLoader(mId, mArgs);
            }
            if (mLoader != null) {
                if (mLoader.getClass().isMemberClass()
                        && !Modifier.isStatic(mLoader.getClass().getModifiers())) {
                    throw new IllegalArgumentException(
                            "Object returned from onCreateLoader must not be a non-static inner member class: "
                            + mLoader);
                }
                if (!mListenerRegistered) { // 是否注册
                    mLoader.registerListener(mId, this);
                    mLoader.registerOnLoadCanceledListener(this);
                    mListenerRegistered = true;
                }
                mLoader.startLoading();
            }
        }

initLoader方法第一步主要是创建LoaderInfo对象,回调ContactEntryListFragment的onCreateLoader方法创建Loader对象, 以及对LoaderInfo的变量状态赋值。

3.2, startLoading

流程图如下,



2个注册监听方法在后面再论述,先论述startLoading方法,到此,开始异步加载了。

开始几个方法兜兜转转,最后会调用onForceLoad方法,该方法如下,

protected void onForceLoad() {
        super.onForceLoad();
        cancelLoad();
        mTask = new LoadTask();
        if (DEBUG) Log.v(TAG, "Preparing load: mTask=" + mTask);
        executePendingTask();
    }

LoadTask继承AsyncTask类,重写了

doInBackground/ onPostExecute/ onCancelled等方法。

executePendingTask方法如下,

void executePendingTask() {
        if (mCancellingTask == null && mTask != null) {
            if (mTask.waiting) {
                mTask.waiting = false;
                mHandler.removeCallbacks(mTask);
            }
            if (mUpdateThrottle > 0) {
                long now = SystemClock.uptimeMillis();
                if (now < (mLastLoadCompleteTime+mUpdateThrottle)) {
                    // Not yet time to do another load.
                    if (DEBUG) Log.v(TAG, "Waiting until "
                            + (mLastLoadCompleteTime+mUpdateThrottle)
                            + " to execute: " + mTask);
                    mTask.waiting = true;
                    mHandler.postAtTime(mTask, mLastLoadCompleteTime+mUpdateThrottle);
                    return;
                }
            }
            if (DEBUG) Log.v(TAG, "Executing: " + mTask);
            mTask.executeOnExecutor(mExecutor, (Void[]) null);
        }
    }

直接调用LoadTask的executeOnExecutor方法开始异步查询。

mExecutor变量在构造方法中赋值为AsyncTask.THREAD_POOL_EXECUTOR。

关于这个THREAD_POOL_EXECUTOR线程池以及AsyncTask原理在此就不论述了。

private final Executor mExecutor;

    public AsyncTaskLoader(Context context) {
        this(context, AsyncTask.THREAD_POOL_EXECUTOR);
    }

    /** {@hide} */
    public AsyncTaskLoader(Context context, Executor executor) {
        super(context);
        mExecutor = executor;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值