转载来源:http://www.cnblogs.com/TerryBlog/archive/2012/02/20/2359051.html
Loader的特点和使用场所
- Loader 可以在Activity 和Fragments 的界面下运行(本篇将结合上篇文章的Fragments的DEMO进行讲述如何在Fragments 下使用Loaders)。
- 它可以提供类似于AysncTask一样的异步请求数据加载的功能,实际上它就是来源于AysncTask 的扩展并增加了很多人性化的功能,例如加载进度框、更好的控制API等。
- 它拥有一个类似于Windows Phone 开发的MVVM一样的数据改变通知机制,当数据源做出改变时会及时通知。
- 当Cursor 发生变化时,会自动加载数据,因此并不需要再重新进行数据查询。
Loader API 使用参考
- LoaderManager
每一个Activity 和 Fragments 只能存在一个LoaderManager,负责管理界面中的Loader。
- LoaderManager.LoaderCallbacks
位于LoaderManager的子接口,提供众多的回调接口操作Loader ,如初始化、创建、重新启动、销毁、结束等一系列实用接口。
- Loader
与Fragments相似,是一个基础类,可以由用户自行扩展适合自己的类
- AsyncTaskLoader
提供了一个基于AsyncTask 工作机制的Loader,查看源码可以看到其继承于Loader,并且子类LoadTask 继承于AsyncTask<Void, Void, D>,并且实现了Runable 接口,功能十分强大。本DEMO就是基于AsyncTaskLoader篇写。
- CursorLoader
提供了一个基于AsyncTaskLoader工作机制的Loader,查看源码可以看到其继承于AsyncTaskLoader,一般继承OnQueryTextListener,可用于查询、更改数据源作用。
Loader 详细使用DEMO
基于上篇的Fragments 代码,添加Loaders功能,实现加载应用程序数据到界面上,DEMO的运行效果如下:
核心代码为
应用程序的数据对象类:
public
static
class AppEntry {
private
final AppListLoader mLoader;
private
final ApplicationInfo mInfo;
private
final File mApkFile;
private String mLable;
private Drawable mIcon;
private
boolean mMounted;
public AppEntry(AppListLoader loader, ApplicationInfo info) {
mLoader = loader;
mInfo = info;
mApkFile =
new File(info.sourceDir);
}
public ApplicationInfo getApplicationInfo() {
return mInfo;
}
public String getLable() {
return mLable;
}
public Drawable getIcon() {
if (mIcon ==
null) {
if (mApkFile.exists()) {
mIcon = mInfo.loadIcon(mLoader.mPm);
return mIcon;
}
else {
mMounted =
false;
}
}
else
if (!mMounted) {
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() {
//
TODO Auto-generated method stub
return mLable.toString();
}
void loadLable(Context mContext) {
if (mLable ==
null || !mMounted) {
if (!mApkFile.exists()) {
mMounted =
false;
mLable = mInfo.packageName;
}
else {
mMounted =
true;
CharSequence lable = mInfo.loadLabel(mContext
.getPackageManager());
mLable = lable !=
null ? lable.toString()
: mInfo.packageName;
}
}
}
}
实现AsyncTaskLoader 加载数据
public
static
class AppListLoader
extends AsyncTaskLoader<List<AppEntry>> {
final InterestingConfigChanges mLastConfig =
new InterestingConfigChanges();
final PackageManager mPm;
List<AppEntry> mApps;
packageIntentReceiver mPackageObserver;
public AppListLoader(Context context) {
super(context);
//
TODO Auto-generated constructor stub
mPm = getContext().getPackageManager();
}
@Override
public List<AppEntry> loadInBackground() {
//
TODO Auto-generated method stub
List<ApplicationInfo> apps = mPm
.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES
| PackageManager.GET_DISABLED_COMPONENTS);
if (apps ==
null)
apps =
new ArrayList<ApplicationInfo>();
final Context mContext = getContext();
List<AppEntry> entries =
new ArrayList<AppEntry>(apps.size());
for (ApplicationInfo info : apps) {
AppEntry entry =
new AppEntry(
this, info);
entry.loadLable(mContext);
entries.add(entry);
}
Collections.sort(entries, ALPHA_COMPARATOR);
return entries;
}
@Override
public
void deliverResult(
List<com.xuzhi.fragment.FragmentDemoActivity.AppEntry> data) {
//
TODO Auto-generated method stub
if (isReset()) {
if (data !=
null) {
//
释放资源处理
}
}
List<AppEntry> oladApps=data;
mApps=data;
if(isStarted()){
super.deliverResult(data);
}
if(oladApps!=
null){
//
释放资源
}
}
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();
}
};
@Override
public
void onCanceled(
List<com.xuzhi.fragment.FragmentDemoActivity.AppEntry> data) {
//
TODO Auto-generated method stub
super.onCanceled(data);
cancelLoad();
}
@Override
protected
void onReset() {
//
TODO Auto-generated method stub
super.onReset();
onStopLoading();
if(mApps!=
null){
//
释放资源
mApps=
null;
}
if(mPackageObserver!=
null){
getContext().unregisterReceiver(mPackageObserver);
mPackageObserver=
null;
}
}
}
实现数据源:
public
static
class AppListAdapter
extends ArrayAdapter<AppEntry>{
private LayoutInflater mInflater;
public AppListAdapter(Context context) {
//
TODO Auto-generated constructor stub
super(context, android.R.layout.simple_list_item_2);
mInflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public
void setData(List<AppEntry> data){
clear();
if(data!=
null){
addAll(data);
}
}
@Override
public View getView(
int position, View convertView, ViewGroup parent) {
//
TODO Auto-generated method stub
View view;
if(convertView==
null){
view=mInflater.inflate(R.layout.list_item_icon_text, parent,
false);
}
else{
view=convertView;
}
AppEntry item=getItem(position);
((ImageView)view.findViewById(R.id.icon)).setImageDrawable(item.getIcon());
((TextView)view.findViewById(R.id.text)).setText(item.getLable());
return view;
}
}
在Activity 或者Fragments 里面实现接口:
public static class DetailsFragment extends ListFragment implements OnQueryTextListener,LoaderCallbacks<List<AppEntry>>
实现接口里面的函数:
public
boolean onQueryTextChange(String newText) {
//
TODO Auto-generated method stub
return
false;
}
public
boolean onQueryTextSubmit(String query) {
//
TODO Auto-generated method stub
return
false;
}
public Loader<List<com.xuzhi.fragment.FragmentDemoActivity.AppEntry>> onCreateLoader(
int id, Bundle args) {
//
TODO Auto-generated method stub
return
new AppListLoader(getActivity());
}
/**
* Load 完成后
*/
public
void onLoadFinished(
Loader<List<com.xuzhi.fragment.FragmentDemoActivity.AppEntry>> arg0,
List<com.xuzhi.fragment.FragmentDemoActivity.AppEntry> arg1) {
//
TODO Auto-generated method stub
mAdapter.setData(arg1);
if (isResumed()) {
setListShown(
true);
}
else {
setListShownNoAnimation(
true);
}
}
/**
* Loader 重置时
*/
public
void onLoaderReset(
Loader<List<com.xuzhi.fragment.FragmentDemoActivity.AppEntry>> arg0) {
//
TODO Auto-generated method stub
mAdapter.setData(
null); }
得到LoaderManager初始化Loader,启动加载在Fragment 的onActivityCreated回调方法上添加,本DEMO的DetailsFragment类添加:
@Override
public
void onActivityCreated(Bundle savedInstanceState) {
//
TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
mAdapter =
new AppListAdapter(getActivity());
setListAdapter(mAdapter);
//
Start out with a progress indicator.
setListShown(
false);
//
Prepare the loader. Either re-connect with an existing one,
//
or start a new one.
getLoaderManager().initLoader(0,
null,
this); }
总结
Loader的使用分为以下几个步骤:
- 实现自己的异步Loader ,如本篇的AsyncTaskLoader或者CursorLoader或者自己继承Loader,第二步需要用到这个Loader
- 创建数据源->public static class AppListAdapter extends ArrayAdapter<AppEntry>
- 在Activity 或者Fragments 上实现OnQueryTextListener,LoaderManager.LoaderCallbacks接口
- 在onCreateLoader里面返回Loader,在onLoadfinished里面做清除动作,在onQueryTextChange或者onQueryTextSubmit改变数据源,在onCreate里面让Loader去执行请求数据getLoaderManager().initLoader(0, null, this);
源代码地址:http://download.csdn.net/detail/jindegegesun/4081259