最近项目中涉及到加载本地的地名.db文件,数据量大,自然不能直接放在UI线程中操作,好在Google在Android3.0以后,提供了AsyncTaskLoader来做一些耗时的异步任务。
一 官方对AsyncTaskLoader的定义及特点介绍如下:
Abstract Loader that provides an AsyncTask to do the work
Introduced in Android 3.0, loaders make it easy to asynchronously load data in an activity or fragment. Loaders have these characteristics:
1、They are available to every Activity and Fragment.
//支持Activity和Fragment
2、They provide asynchronous loading of data.
//异步下载 (就是不影响UI线程)
3、They monitor the source of their data and deliver new results when the content changes.
//当数据源改变时能及时通知客户端
4、They automatically reconnect to the last loader’s cursor when being recreated after a configuration change. Thus, they don’t need to re-query their data.
//发生configuration change时自动重连接
二 实际项目介绍
下面引用官方的一个展示当前设备所有已安装应用程序的DEMO,来对AsyncTaskLoader的用法做一个详细的介绍:
项目结构如图:
第一步:我们需要写一个对应于每一个应用程序的实体类,该实体类包含应用程序图标和标签两个属性。
AppEntry.java:
/**
* Created by Administrator on 2016/5/25.
*/
public class AppEntry {
private String mLabel;//应用文字标签
private Drawable mIcon;//应用图标
private final AppListLoader mLoader;
private final ApplicationInfo mInfo;//<application>节点信息,只有一个
//PackageInfo、ApplicationInfo、ActivityInfo、ResolveInfo四种信息类的一种
private final File mApkFile;
private boolean mMounted;
public AppEntry(AppListLoader mLoader,ApplicationInfo mInfo ) {
this.mInfo = mInfo;
this.mLoader = mLoader;
mApkFile=new File(mInfo.sourceDir);//sourceDir=Full path to the location of this package
}
public ApplicationInfo getApplicationInfo() {
return mInfo;
}
public String getLabel() {
return mLabel;
}
public Drawable getIcon() {
if (mIcon == null) {
if (mApkFile.exists()) {
mIcon = mInfo.loadIcon(mLoader.mPm);
//public Drawable loadIcon (PackageManager pm){}获取应用图标
return mIcon;
} else {
mMounted = false;
}
} else if (!mMounted) {
// If the app wasn't mounted but is now mounted, reload its icon.
if (mApkFile.exists()) {
mMounted = true;
mIcon = mInfo.loadIcon(mLoader.mPm);
return mIcon;
}
} else {
return mIcon;
}
return mLoader.getContext().getResources()
.getDrawable(android.R.drawable.sym_def_app_icon);//否则返回默认的小机器人
}
@Override
public String toString() {
return mLabel;
}
void loadLabel(Context context) {
if (mLabel == null || !mMounted) {
if (!mApkFile.exists()) {
mMounted = false;
mLabel = mInfo.packageName;//获取程序名称
} else {
mMounted = true;