public Loader initLoader(int id, Bundle args, LoaderManager.LoaderCallbacks callback) {
if (mCreatingLoader) {
throw new IllegalStateException("Called while creating a loader");
}
//集合中获取指定的LoaderInfo
LoaderInfo info = mLoaders.get(id);
if (DEBUG) Log.v(TAG, "initLoader in " + this + ": args=" + args);
if (info == null) {
// 不存在就创建一个LoaderInfo
info = createAndInstallLoader(id, args, (LoaderManager.LoaderCallbacks
具体创建的源码createAndInstallLoader 方法
private LoaderInfo createAndInstallLoader(int id, Bundle args,
LoaderManager.LoaderCallbacks callback) {
try {
mCreatingLoader = true;
//创建LoaderInfo
LoaderInfo info = createLoader(id, args, callback);
//创建后的操作 处理
installLoader(info);
return info;
} finally {
mCreatingLoader = false;
}
}
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
//LoaderInfo的start()开启
info.start();
}
}
现在看看info.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) {
//回调操作 在Activity中或者Fragment中 这里是我们上面使用的三个回调的第一个
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) {
//这里是注册 将自己给注册到Loader的提供的接口上 让Loader回调这里实现相关操作 因为后续使用AsyncTaskLoader回调的时候 可以操作LoaderInfo的Callback回调
mLoader.registerListener(mId, this);
mLoader.registerOnLoadCanceledListener(this);
mListenerRegistered = true;
}
//loader开始载入
mLoader.startLoading();
}
}
final class LoadTask extends AsyncTask implements Runnable {
private final CountDownLatch mDone = new CountDownLatch(1);
// Set to true to indicate that the task has been posted to a handler for
// execution at a later time. Used to throttle updates.
boolean waiting;
/* Runs on a worker thread */
@Override
protected D doInBackground(Void... params) {
*****省略****
D data = AsyncTaskLoader.this.onLoadInBackground();
return data;
*****省略****
}
/* Runs on the UI thread */
@Override
protected void onPostExecute(D data) {
if (DEBUG) Log.v(TAG, this + " onPostExecute");
try {
//后台任务完成后 来到这里 这里按照我们的逻辑来看应该是执行LoaderManager的onfinish()完成的回调
AsyncTaskLoader.this.dispatchOnLoadComplete(this, data);
} finally {
mDone.countDown();
}
}
/* Runs on the UI thread */
@Override
protected void onCancelled(D data) {
if (DEBUG) Log.v(TAG, this + " onCancelled");
try {
AsyncTaskLoader.this.dispatchOnCancelled(this, data);
} finally {
mDone.countDown();
}
}
}
void dispatchOnLoadComplete(LoadTask task, D data) {
if (mTask != task) {
if (DEBUG) Log.v(TAG, "Load complete of old task, trying to cancel");
dispatchOnCancelled(task, data);
} else {
if (isAbandoned()) {
// This cursor has been abandoned; just cancel the new data.
onCanceled(data);
} else {
commitContentChanged();
mLastLoadCompleteTime = SystemClock.uptimeMillis();
mTask = null;
if (DEBUG) Log.v(TAG, "Delivering result");
//分发结果 胜利就在眼前
deliverResult(data);
}
}
}
public void deliverResult(D data) {
if (mListener != null) {
//这里就是上面LoaderManagerImpl 注册的时候把自己注册上去的回调
mListener.onLoadComplete(this, data);
}
}
static class Bakery extends BroadcastReceiver {
final Baker mBaker;
public static String CUSTOMER_ACTION = "com.daemon.demo" ;
public Bakery(Baker baker) {
mBaker = baker;
IntentFilter filter = new IntentFilter(CUSTOMER_ACTION);
baker.getContext().registerReceiver(this, filter);
}
@Override public void onReceive(Context context, Intent intent) {
//主要是这个方法 来通知更新
mBaker.onContentChanged();
}
}
public void onContentChanged() {
if (mStarted) {
// 发现和上面的Loader onstartLoading那一步
forceLoad();
} else {
// This loader has been stopped, so we don't want to load
// new data right now... but keep track of it changing to
// refresh later if we start again.
mContentChanged = true;
}
}
现在来一个例子 例子是网上看着别人的 自己用在ListView显示 一个添加数据的按钮
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.lvshow = (ListView) findViewById(R.id.lv_show);
this.btadd = (Button) findViewById(R.id.bt_add);
mBaker = new Baker(this);
mBakery = new Bakery(mBaker,this);
list=new ArrayList();
myAdpater=new MyAdpater(this,list);
lvshow.setAdapter(myAdpater);
mCallbacks = new LoaderManager.LoaderCallbacks>() {
@Override
public Loader> onCreateLoader(int id, Bundle args) {
if (mBaker == null) {
mBaker = new Baker(MainActivity.this);
}
return mBaker;
}
@Override
public void onLoadFinished(Loader> loader, List data) {
list.addAll(data);
myAdpater.notifyDataSetChanged();
//面包师完成面包烤制
LogUtils.e("sell " + data.size() + " breads");
}
@Override
public void onLoaderReset(Loader> loader) {
}
};
//面包师开始工作
getLoaderManager().initLoader(0, null, mCallbacks);
btadd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Bakery.CUSTOMER_ACTION);
sendBroadcast(intent);
}
});
}
Baker
public class Baker extends AsyncTaskLoader> {
public Baker(Context context) {
super(context);
}
@Override
public List loadInBackground() {
List breads = new ArrayList();
//获得当前需要做的面包
for (int i = 0; i < 5; i++) {
//制作面包,耗时操作
breads.add("123"+i);
}
//面包制作完成
return breads;
}
@Override
public void deliverResult(List data) {
super.deliverResult(data);
}
@Override
protected void onStartLoading() {
forceLoad();
}
@Override
protected void onStopLoading() {
cancelLoad();
}
@Override
protected void onReset() {
super.onReset();
}
}
Bakery
public class Bakery extends BroadcastReceiver {
final Baker mBaker;
public static String CUSTOMER_ACTION = "com.daemon.demo" ;
public Bakery(Baker baker , Context context) {
mBaker = baker;
IntentFilter filter = new IntentFilter(CUSTOMER_ACTION);
context.registerReceiver(this, filter);
}
@Override
public void onReceive(Context context, Intent intent) {
mBaker.onContentChanged();
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml&q