【安卓】如何使用Loaders

Loaders已经成为获取数据库或者内容提供者中的数据的首选方案。

它可以异步的加载数据并当数据改变时及时提醒监听器。

Google不仅仅是推荐你使用Loader,而且deprecated 掉一些先前处理Cursor的方法。现在你不应该在你的项目中再使用startManagingCursor()和managedQuery()方法了。

使用cursor查询通常是执行在主线程(UI Thread)中,这可能会使应用有些反应迟钝甚至会导致ANR(application not responding)问题,而使用Loaders将不会再阻塞你的主线程。

在这篇博客中我将介绍Loader API中一些主要的类并向您展示如何使用他们。

Loader API中主要的类和接口

【安卓】如何使用Loaders_第1张图片

下面我将逐一介绍这些类,首先从LoaderManager开始吧!

LoaderManager

这个类使你的Loaders与Activity以及Frgament的生命周期保持一致。如果销毁了Frgament或者Activity,那么LoaderManager将会释放Loaders占用的资源。总之,这个类比先前的startManagingCursor或者managedQuery方法更加厉害。

 

你并不需要自己实例化这个类,仅需在Activity或者Frgament中调用getLoaderManager()方法即可。

通常情况下你仅需要了解下面两个方法就足够了:

1.initLoader()

2.restartLoader()

 

 

initLoader()

这个方法将向LoaderManager中添加一个Loader:

getLoaderManager().initLoader(id, bundle, callbacks);

 

;

该方法需要传入三个参数:

一个id号用来唯一标识Loader,一个Bundle对象,以及LoaderCallbacks接口。

你可能需要一个id号以便于将来调用方便,所以请尽量将id号声明为final static的,这样会使你的代码可读性更好。Bundle用来为你的Loader传递一些可选的参数,但是对于CursorLoader并不适用。第三个参数,LoaderCallbacks,我们在下面将会详细介绍。

initLoader方法创建一个新的Loader的前提是对应的id号之前没有被使用过。需要牢记的是系统会为你处理配置改变的情形,所以一些小小的变化都会都会调用initLoader方法,在这种情形下,这个方法会返回已有的实例所以你的查询操作将不会被再次执行。

restartLoader()

因为系统不会再次处理查询操作,所以需要一个方法重新加载Loader当数据发生改变时,你可以使用restartLoader方法来重置Loader,它的参数类型和initLoader一样,当然你需要传入一个和初始化Loader时相同的id号。

getLoaderManager().restartLoader(id, bundle, callbacks);

LoaderManager.LoaderCallbacks

你必须要实现这个接口中的方法以便于处理查询结果或者清理资源,这个接口是泛型化的所以你必须要传入一个Loader的数据类型。通常情况下为Cursaor:


你必须实现的方法如下:

onCreateLoader()

onLoadFinished()

onLoadReset()

 

下面我们逐一解释每个方法的作用:

onCreateLoader()

当你第一次调用initLoader时会调用此方法。就像之前提到过的,前提是对应的ID不存在。

另外还需要传递一个int类型和一个bundle类型的参数,这跟initLoader中的参数意义是一样的。

 

一个典型的创建CursorLoader的示例代码如下:

【安卓】如何使用Loaders_第2张图片

我们可以看到CursorLoader中的参数就是ContentResolver处理查询操作所需的参数。

如果你需要执行不同的查询操作并因此使用了不同的id创建Loaders,你仅需增加一个if-else分支判断即可。

onLoadFinished()

这个方法最有意思了,你可以在这里根据查询的结果更新你的UI。如果是ListAdapter的话仅需swap一下cursor即可。否则你需要得到view对象相关控件的引用并根据结果对其赋值。

示例代码如下:【安卓】如何使用Loaders_第3张图片


onLoadReset()

 

这个方法允许你释放你持有的资源,以便Loader来释放它们。你可以将相关对象置为null但是不要关闭cursor,因为Loader会帮我们完成。

 

 

 

 

Loader,AsyncTaskLoader and CursorLoader

Loader及其实现类并不是很有意思除非你编写自己的Loader。当然你不得不创建一个Loader,但是除了使用构造器创建CursorLoader你几乎不和这些对象打交道。

如果你使用不同的Loader你需要在callbacks方法中获取它们的id,可以通过在Loader中调用getId()方法传递给callbacks。

 

使用CursorLoader需要注意的地方

通常我们都会把cursorLoader作为ListView或者AutoCompleteTextViews 等控件的数据源。在使用Loader时务必得小心:

首先,Cursor对象在onLoadFinished方法调用之前是不存在的,换句话说,当你创建好了适配器,Cursor对象未必可用,所以当你创建适配器时需要将cursor参数置空:


【安卓】如何使用Loaders_第4张图片

当cursor对象可用时你必须加上它,可以使用在适配器中调用swapCursor方法:

【安卓】如何使用Loaders_第5张图片


在onLoadReset方法中清理资源时重新调用swapCursor方法并传入null


Use theSupport Library for older Android versions

为了兼容老版本,google提供了扩展库,最主要的包括Frgament和Loader。

你应该尽量使用扩展库中的API以使你的应用兼容性更好。但是在你导包的时候务必睁大眼睛报名开头是android.support.v4:


通过继承FrgamentActivity,获取LoaderManager实例的方法变为getSupportLoaderManager()。

 

Whennot to use Loaders

如果你需要你的后台任务完成的话请不要使用Loader。因为Loader会随着Frgament或者Activity的销毁而销毁。如果需要执行一些后台任务,请使用service代替。




原文地址:http://www.grokkingandroid.com/using-loaders-in-android/




你可能感兴趣的:(安卓,loader)