装载器从android3.0开始引进。它使得在activity或fragment中异步加载数据变得简单。android
当成批显示数据的时候,为了使用户体验更好,须要进行异步装载。也就是说,让未显示数据的ListView等UI组件或控件先显示,避免出现白屏的尴尬现象,同时在后台下载数据,等下载完成后再更新ListView组件。这样尽管用户不会马上看到数据,可是也不至于网络速度缓慢或服务器响应不及时而形成假死现象。数据库
装载器具备以下特性:服务器
它们对每一个Activity和Fragment都有效;网络
他们提供了异步加载数据的能力;app
它拥有一个数据改变通知机制,当数据源作出改变时会及时通知。 也就是能够监听数据源,一旦数据源发生变化,Loader会感知这些变化;异步
当Cursor 发生变化时,会自动加载数据,所以并不须要再从新进行数据查询。ide
android设计Loader的初衷是想让你们像CursorLoader的作法同样,经过loader去维护数据,每次启动loader时先检查有没有旧的数据并把旧的数据先deliver给用户,而后再考虑要不要从新加载新的数据。布局
在使用装载器时,会涉及不少类和接口们,在下表中对它们总结一下:this
Class/Interface | 说明 |
LoaderManager | 一个抽像类,关联到一个Activity或Fragment,管理一个或多个装载器的实例。这帮助一个应用管理那些与Activity或Fragment的生命周期相关的长时间运行的的操做。最多见的方式是与一个CursorLoader一块儿使用,然而应用是能够随便写它们本身的装载器以加载其它类型的数据。 每一个activity或fragment只有一个LoaderManager。可是一个LoaderManager能够拥有多个装载器。 |
LoaderManager.LoaderCallbacks | 一个用于客户端与LoaderManager交互的回调接口。例如,你使用回调方法onCreateLoader()来建立一个新的装载器。 |
Loader(装载器) | 一个执行异步数据加载的抽象类。它是加载器的基类。你可使用典型的CursorLoader,可是你也能够实现你本身的子类。一旦装载器被激活,它们将监视它们的数据源而且在数据改变时发送新的结果。 |
AsyncTaskLoader | 提供一个AsyncTask来执行异步加载工做的抽象类。 |
CursorLoader | AsyncTaskLoader的子类,它查询ContentResolver而后返回一个Cursor。这个类为查询cursor以标准的方式实现了装载器的协议,它的游标查询是经过AsyncTaskLoader在后台线程中执行,从而不会阻塞界面。使用这个装载器是从一个ContentProvider异步加载数据的最好方式。相比之下,经过fragment或activity的API来执行一个被管理的查询就不行了。 |
二AsyncTaskLoader示例:
(一)、AsyncTaskLoader 实现数据加载的步骤:
一、窗体Activity要实现LoaderManager.LoaderCallbacks<Cursor>接口。至于继承于Activity仍是FragmentActivity要看是否须要支持3.0如下的版本。若是须要兼容则继承与FragmentActivity。
2.建立LoaderManager对象,经过getLoaderManager()或getSupportLoaderManager()方法实现。若是是继承FragmentActivity,则使用getSupportLoaderManager()方法建立,不然使用前者便可。
三、初始化LoaderManager对象,调用initLoader()方法来初始化;
四、操做ListView空间对象:先findViewByID(),而后setAdapter();
【备注】此时必须使用SimpleCursorAdapter适配器,而构建适配器的时候,第三个参数Cursor设置为null,最后一个参数:flags必须是:CursAdapter.FLAG_REGISTER_CONTENT_OBSERVER。
五、自定义Loader,做为onCreateLoader()的返回值
FLAG_AUTO_REQUERY
andFLAG_REGISTER_CONTENT_OBSERVER。
当一个已建立的装载器被重置从而使其数据无效时,此方法被调用.此回调使你能发现何时数据将被释放。你能够释放对它的引用。
(四)、AsyncTaskLoader中各个方法的执行顺序:
04-01 04:00:25.477: MainActivity: ==onCreate 04-01 04:00:25.701: LoaderCallbacks: ==onCreateLoader 04-01 04:00:25.705: AsyncTaskLoader: ==onStartLoading 04-01 04:00:25.709: AsyncTaskLoader: ==loadInBackground 04-01 04:00:25.721: AsyncTaskLoader: ==deliverResult 04-01 04:00:25.721: LoaderCallbacks: ==onLoadFinished 04-01 04:00:25.749: MainActivity: ==onStart 04-01 04:00:25.749: MainActivity: ==onResume 04-01 04:00:25.973: MainActivity: ==onCreateOptionsMenu
(五)、当另外一个app修改了同一个数据源(如:共同使用的SDCard上的数据库)后AsyncTaskLoader中各个方法的执行顺序:
04-01 04:01:06.693: MainActivity: ==onPause 04-01 04:01:08.413: MainActivity: ==onStop 04-01 04:01:15.721: AsyncTaskLoader: ==onStartLoading 04-01 04:01:15.721: AsyncTaskLoader: ==loadInBackground 04-01 04:01:15.721: AsyncTaskLoader: ==deliverResult 04-01 04:01:15.721: LoaderCallbacks: ==onLoadFinished 04-01 04:01:15.757: MainActivity: ==onStart 04-01 04:01:15.757: MainActivity: ==onResume
(三)、示例代码:
publicclass MainActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor> { private ListView listView_main; private LoaderManager manager; privatestatic SimpleCursorAdapter adapter; @Override protectedvoid onCreate(Bundle arg0) { super.onCreate(arg0); setContentView(R.layout.activity_main); listView_main = (ListView) findViewById(R.id.listView_main); manager = getSupportLoaderManager(); manager.initLoader(0, null, this); adapter = new SimpleCursorAdapter(this, R.layout.item_listview_main, null, new String[] { "_id", "title" }, newint[] { R.id.text_item_title, R.id.text_item_content }, 2); listView_main.setAdapter(adapter); } @Override public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) { Log.i("Activity", "===onCreateLoader"); returnnew MyLoader(this); } @Override publicvoid onLoadFinished(Loader<Cursor> arg0, Cursor arg1) { Log.i("Activity", "===onLoaderFinished"); adapter.swapCursor(arg1); } @Override publicvoid onLoaderReset(Loader<Cursor> arg0) { Log.i("Activity", "===onLoaderReset"); } staticclass MyLoader extends AsyncTaskLoader<Cursor> { private Context context; public MyLoader(Context context) { super(context); this.context = context; } @Override protectedvoid onStartLoading() { super.onStartLoading(); Log.i("MyLoader", "===onStartLoading"); forceLoad(); } @Override public Cursor loadInBackground() { Log.i("MyLoader", "===loadInBackground"); MySQLiteDatabaseHelper dbHelper = new MySQLiteDatabaseHelper(); Cursor cursor = dbHelper.selectCursor( "select id as _id , title from android_info limit 0,20", null); deliverResult(cursor); return cursor; } @Override publicvoid deliverResult(Cursor data) { Log.i("MyLoader", "===deliverResult"); super.deliverResult(data); adapter.swapCursor(data); } } }