Loaders在Android 3.0版本后引入。Loaders使异步加载数据更加容易。Loaders有如下的特性:
1.它们适用于任何Activity和Fragment;
2. 它们提供了异步加载数据的机制;
3. 它们检测数据源,当数据源内容改变时它们能够传递新的结果;
4. 当配置改变后需要重新创建时,它们会重新连接到最后一个loader的游标。这样,它们不需要重新查询它们的数据。
根据官方API DEMO中的LoaderCustom类整理的Demo,功能是通过Loader异步加载手机中所有的APP应用。
/**
* 展示手机中所有应用程序列表的页面
*
* @description:
* @author ldm
* @date 2016-5-5 上午9:26:28
*/
public class AppsActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fm = getFragmentManager();
// 系统定义的此Fragment的id为android.R.id.content
if (fm.findFragmentById(android.R.id.content) == null) {
AppListFragment list = new AppListFragment();
// 添加 Fragment
fm.beginTransaction().add(android.R.id.content, list).commit();
}
}
}
/**
* SearchView.OnQueryTextListener:的实现在用户查询发生改变时重启了装载器,
* 装载器于是需重启从而能使用新的搜索过虑来进行一次新的查询.
* SearchView.OnCloseListener:当用户关闭SearchView时触发的回调函数
* LoaderManager:是加载器的管理器,一个LoaderManager可以管理一个或多个Loader
* ,一个Activity或者Fragment只能有一个LoadManager。 LoaderManager管理Loader的初始化,重启和销毁操作。
* LoaderManager.LoaderCallBacks:用来向客户返回数据的方式
*
* @description:
* @author ldm
* @date 2016-5-5 上午9:29:33
*/
public class AppListFragment extends ListFragment implements
OnQueryTextListener, OnCloseListener,
LoaderManager.LoaderCallbacks
**
* 在Android3.0中引入了AsyncTaskLoader装载器功能类,这使它很容易在Activity或Fragment中使用异步的方式加载数据。
* 装载器的特点如下:
*
* 1. 装载器对于每个Activity和Fagment都是有效的;
*
* 2. 装载器提供异步数据加载的能力;
*
* 3. 装载器监视数据资源并且当内容改变时发送新的结果;
*
* 4. 在配置改变后重建的时候,装载器自动的重连最后的装载器游标,因此,不需要重新查询数据。
*
* @description:
* @author ldm
* @date 2016-5-4 下午6:06:20
*/
public class AppListLoader extends AsyncTaskLoader<List<AppEntry>> {
private InterestingConfigChanges mLastConfig = new InterestingConfigChanges();
public PackageManager mPm;
private List<AppEntry> mApps;
private PackageIntentReceiver mPackageObserver;
public AppListLoader(Context context) {
super(context);
// 初始化包管理PackageManager对象
mPm = getContext().getPackageManager();
}
/**
* 根据指定标志排序
*/
private static final Comparator<AppEntry> ALPHA_COMPARATOR = new Comparator<AppEntry>() {
private final Collator sCollator = Collator.getInstance();
@Override
public int compare(AppEntry object1, AppEntry object2) {
return sCollator.compare(object1.getLabel(), object2.getLabel());
}
};
/**
* 这是Loader的核心方法,必须重载,后台运行。在这里头实现加载数据的功能
*/
@Override
public List<AppEntry> loadInBackground() {
// GET_UNINSTALLED_PACKAGES代表已删除,但还有安装目录的
// GET_DISABLED_COMPONENTS获取所有组件
List<ApplicationInfo> apps = mPm
.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES
| PackageManager.GET_DISABLED_COMPONENTS);
if (apps == null) {
apps = new ArrayList<ApplicationInfo>();
}
final Context context = getContext();
List<AppEntry> entries = new ArrayList<AppEntry>(apps.size());
for (int i = 0; i < apps.size(); i++) {
AppEntry entry = new AppEntry(this, apps.get(i));
entry.loadLabel(context);
entries.add(entry);
}
// 排序
Collections.sort(entries, ALPHA_COMPARATOR);
// 返回数据结果
return entries;
}
/**
* 将结果传递给已注册的监听器们。
*/
@Override
public void deliverResult(List<AppEntry> apps) {
if (isReset()) {
if (apps != null) {
onReleaseResources(apps);
}
}
List<AppEntry> oldApps = mApps;
mApps = apps;
if (isStarted()) {
super.deliverResult(apps);
}
if (oldApps != null) {
onReleaseResources(oldApps);
}
}
/**
* 开始Loader数据
*/
@Override
protected void onStartLoading() {
if (mApps != null) {
// 一个结果,立即传递结果
deliverResult(mApps);
}
// 通过广播监听数据改变
if (mPackageObserver == null) {
mPackageObserver = new PackageIntentReceiver(this);
}
boolean configChange = mLastConfig.applyNewConfig(getContext()
.getResources());
if (takeContentChanged() || mApps == null || configChange) {
forceLoad();
}
}
/**
* 停止Loader数据
*/
@Override
protected void onStopLoading() {
// 取消当前的加载任务
cancelLoad();
}
@Override
public void onCanceled(List<AppEntry> apps) {
super.onCanceled(apps);
onReleaseResources(apps);
}
@Override
protected void onReset() {
super.onReset();
// 停止加载
onStopLoading();
// 释放资源
if (mApps != null) {
onReleaseResources(mApps);
mApps = null;
}
if (mPackageObserver != null) {
getContext().unregisterReceiver(mPackageObserver);
mPackageObserver = null;
}
}
protected void onReleaseResources(List<AppEntry> apps) {
}
}
只贴了三个类的代码,说明及注释我习惯放在代码中,Demo项目参考:http://download.csdn.net/detail/true100/9510613
开源代码:https://github.com/ldm520/ANDROID_API_DEMOS