Loader是一个很有意思的异步加载工具,能够很优雅的监听数据更新,并传递给我们。而且Loader非常聪明,接下来简单介绍一下它的使用方法以及它聪明的地方。
Loader使用其实是很简单的,逻辑很清晰:
1.通过Activity\Fragment的getLoaderManager().initLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<D> callBack)进行初始化。id代表当前Loader的标识,虽然一个Fragment或者Activity中只存在一个 LoaderManager,但是可以存在多个Loader,此id用于标识不同的Loader;args则是传递给Loader的Bundle类型的参数;callBack则是一个回调。
2.接着我们实现 LoaderManager.LoaderCallbacks<D>接口的三个回调方法。
onCreate() -- 创建一个Loader并且返回给LoaderManager(一般使用CursorLoader)
onLoaderFinished() -- Loader加载完成以后调用 ,返回结果
onLoaderReset() -- Loader重置以后,不加载数据
3.继承AsyncTaskLoader,重写loadInBackground方法,这里方法运行在子线程,可以执行耗时程序。当耗时操作执行完毕之后,会通过回调方法onLoaderFinished告诉我们。
ok,完整小例子奉上:
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<String>{
private LoaderText mLoaderText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mLoaderText = new LoaderText(this);
getLoaderManager().initLoader(2, null, this);
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//通知有数据更新
mLoaderText.onContentChanged();
}
}
}).start();
}
@Override
public Loader<String> onCreateLoader(int i, Bundle bundle) {
Log.d("~", "onCreateLoader");
return mLoaderText;
}
@Override
public void onLoadFinished(Loader<String> loader, String s) {
Log.d("~", "onLoadFinished " + s);
}
@Override
public void onLoaderReset(Loader<String> loader) {
Log.d("~", "onLoaderReset");
}
}
public class LoaderText extends AsyncTaskLoader<String> {
public LoaderText(Context context) {
super(context);
}
@Override
public String loadInBackground() {
Log.d("~", "loadInBackground");
Random random = new Random();
int mNeededBreads =random.nextInt(100);
try {
//模拟耗时操作
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return String.valueOf(mNeededBreads);
}
}
上面很关键的一句代码:mLoaderText.onContentChanged();
如果我们有数据更新,必须通过调用这个方法来通知AsyncTaskLoader。
还有一个类需要提一下CursorLoader,作用与AsyncTaskLoader类似,不过CursorLoader用于加载contentProvider里面提供的数据,可以实现动态监听,而AsyncTaskLoader是异步任务的加载,需要我们手动提示数据更新。
当然刚才我们说了Loader很聪明,聪明在什么地方呢,当我们告诉AsyncTaskLoader有数据更新,它会尝试重新获取数据,如果获取到的数据与之前是完全相同的话,是不会回调onLoadFinished方法的。大家可以尝试一下。