Android 后台任务(四)Loader
翻译自:http://blog.stylingandroid.com/archives/833
转载请注明:http://blog.csdn.net/liaoqianchuan00/article/details/23949765
在前面的文章中我们学习了AsyncTask的使用,也了解了新手使用他的时候的问题和潜在的内存泄露问题。这篇文章我们讲讲Honeycomb Loader的使用。
在开始之前,需要指出虽然Loader在HoneycombAPI11才引入,但是我们也可以在老的版本中使用SupportLibrary来是用Loader。在Honeycomb之前使用Loader,你必须使用FragmentActivity来替代Activity,这样你才能获得LoaderManager的一个实例。这应该不是一个问题。虽然我不需要为平板和手机提供不同的UI,我仍然会经常使用Fragments,因为他提供了很多有用的功能。这将会在另外的文章中讨论。
Loader机制是专门面向从数据库,文件系统,网络读取数据的一个后台任务。可以很有效率的执行一些耗时任务。
我们需要用到3个基本的组件:
1. LoaderManager:用来管理一个或者多个Loader实例。
2. Loader:这个用来执行你的后台任务。
3. LoaderManager.LoaderCallbacks:这个就是你需要实现的用来管理Loader生命周期的interface。
为了使用Loader,你需要做得第一件事情就是获得LoaderManager的实例。可以从Activity对象中获得(但是只能是API11或者以上的版本),或者从Fragment或者FragmentActivity(使用Support Library的时候就可以在老版本中使用了):
接下来我们需要做得就是实现LoaderManager.LoaderCallbacks,这个是管理Loader的一个回调,你可以在里面创建loader,在loader finished或者reset的时候得到通知。这些都会在UI线程中执行,我们一般会结合Activity或者FragmentActivity来使用他。我们将它和Loader分在两个class中来实现,这样就在逻辑上分离了UI线程上得工作和后台线程的工作,因为他们已经在两个分开的class中了。这样就减少了我们前面文章提到的风险(比如在AsyncTask的onPreExecute来执行网络请求)。在UI线程上执行的code都和Activity或者FragmentActivity结合使用,也就意味着我们不能在这里面做一些太耗时的操作,应该让这些操作在Loader里面去做。
我们的Activity看起来像下面这个样子:
public class LoaderActivity extends Activity implements LoaderCallbacks<String> { @Override public void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); setContentView( R.layout.main );
LoaderManager lm = getSupportLoaderManager(); Loader<String> loader = lm.restartLoader( 0, null, this ); loader.forceLoad(); }
@Override public Loader<String> onCreateLoader( int id, Bundle args ) { return new MyLoader( this ); }
@Override public void onLoadFinished( Loader<String> loader, String str ) { Toast.makeText( this, str, Toast.LENGTH_SHORT ).show(); }
@Override public void onLoaderReset( Loader<String> loader ) { } } |
事实上我们实现的这些事情都合我们之前用AsyncTask得方式很像。事实上,有个基于AsyncTask的AsyncTaskLoader类我们可以继承。我们唯一需要在AsyncTaskLoader中做的就是去试想AsyncTask方式中得doInBackground中得事情。
public class MyLoader extendsAsyncTaskLoader<String>
{
public MyLoader( Contextcontext )
{
super(context );
}
@Override
public StringloadInBackground()
{
Stringret = null;
// Dosomething which
//populates ret
returnret;
}
}
这里只介绍了一些Loader的简单用法,更多的可以参考developer.android.com。
下节我们将介绍如何使用Service来进行后台操作。
总结:
Loader自己管理的Activityconfiguration变化的情况(比如旋转屏幕,不会内存泄露)
Loader不能实施更新UI,比如进度条。