1、CursorLoader使用Demo

public class MainActivity extends Activity implements  LoaderManager.LoaderCallbacks<Cursor> {

String TITLE = MediaStore.Audio.Media.TITLE;
String SINGER = MediaStore.Audio.Media.ARTIST;
String SONGURL = MediaStore.Audio.Media.DATA;
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

private LoaderManager loaderManager;

private Cursor myCursor;

private ListView lv;
private SimpleCursorAdapter adapter;
private String songUrl;

/**
* 创建loader之后, 会在子线程执行loadInBackground()方法进行加载数据
*/

@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {

CursorLoader loader = new CursorLoader(this, uri, null, null, null,null);

return loader;
}

/**
* loader加载数据完成,返回一个cursor对象,供我们查询数据
*/

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
myCursor = cursor;
Cursor oldCursor = adapter.swapCursor(cursor);
Log.e("tag", "onLoadFinished: " + oldCursor);
}

/**
* loader重置时回调,需要释放对这个loader数据有引用的cursor
*/

@Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);
intiData();
loaderManager = getLoaderManager();

//调用该方法后会回调onCreateLoader来创建loader对象
loaderManager.initLoader(1, null, this);

}

private void intiData() {
lv = (ListView) findViewById(R.id.lv);
adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, null,

                  new String[] {TITLE, SINGER }, new int[] { android.R.id.text1, android.R.id.text2 },

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {

myCursor.moveToPosition(position);
songUrl = myCursor.getString(myCursor.getColumnIndex(SONGURL));

Log.e("tag", "clickStart: " + songUrl);

}
});

}

public void clickStart(View view) {
Intent i = new Intent(MainActivity.this, MusicService.class);
i.setAction("pause");
// i.putExtra("id", songUrl);
startService(i);
Log.e("tag", "clickStart: ");
// Log.e("tag", "clickStart: " );
}

public void clickStop(View view) {
Intent i = new Intent(MainActivity.this, MusicService.class);
i.setAction("stop");
startService(i);
}
}

2、AsyncTaskLoader详细使用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);

}

参考资料:

Android Loaders(一)概述

Android Loaders(二)Loader的使用

Android Loaders(三)实现一个Base Loader

Android Loader使用详解的更多相关文章

  1. android:ToolBar详解

    android:ToolBar详解(手把手教程) 泡在网上的日子 发表于 2014-11-18 12:49 第 124857 次阅读 ToolBar 42 来源 http://blog.mosil.b ...

  2. Android之canvas详解

    首先说一下canvas类: Class Overview The Canvas class holds the "draw" calls. To draw something, y ...

  3. 【转】Android Canvas绘图详解(图文)

    转自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html Android Canvas绘图详解(图文) 泡 ...

  4. Android 核心分析 之八Android 启动过程详解

    Android 启动过程详解 Android从Linux系统启动有4个步骤: (1) init进程启动 (2) Native服务启动 (3) System Server,Android服务启动 (4) ...

  5. Android GLSurfaceView用法详解(二)

    输入如何处理       若是开发一个交互型的应用(如游戏),通常需要子类化 GLSurfaceView,由此可以获取输入事件.下面有个例子: java代码: package eoe.ClearTes ...

  6. Android编译过程详解(一)

    Android编译过程详解(一) 注:本文转载自Android编译过程详解(一):http://www.cnblogs.com/mr-raptor/archive/2012/06/07/2540359 ...

  7. android屏幕适配详解

    android屏幕适配详解 官方地址:http://developer.android.com/guide/practices/screens_support.html 一.关于布局适配建议 1.不要 ...

  8. Android.mk文件详解(转)

    源:Android.mk文件详解 从对Makefile一无所知开始,折腾了一个多星期,终于对Android.mk有了一个全面些的了解.了解了标准的Makefile后,发现Android.mk其实是把真 ...

  9. Android Studio 插件开发详解四:填坑

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78265540 本文出自[赵彦军的博客] 在前面我介绍了插件开发的基本流程 [And ...

随机推荐

  1. row_number()over(partition by 字段 order by 字段)ID,修改重复行的字段值。

    案例分析: 现在要查询一个表单里面的运费结果,但是他还有分录,为了显示分录,必须把表头显示出来,问题是,他要查询运费的合计, 但是这样就会导致重复行也加进去了,这样显然数据不准,为此,可以把重复的行设 ...

  2. 如何用 CSS 做到完全垂直居中

    本文将教你一个很有用的技巧——如何使用 CSS 做到完全的垂直居中.我们都知道 margin:0 auto; 的样式能让元素水平居中,而 margin: auto; 却不能做到垂直居中……直到现在.但 ...

  3. KeyBord事件从Activtiy层往下分发详细过程代码示例

    step1:调用Activity成员函数dispatchKeyEvent public boolean dispatchKeyEvent(KeyEvent event) { // Let action ...

  4. usb驱动开发23之驱动生命线

    关于字符串描述符的地位仅次于设备/配置/接口/端点四大描述符,那四大设备必须得支持,而字符串描述符对设备来说则是可选的,这并不是就说字符串描述符不重要,对咱们来说,提供字符串描述符的设备要比没有提供的 ...

  5. CSS3 动画效果带来的bug

    css3 动画效果比如transition:all 2s linear;这种用来计算及时的物体坐标的话会带来一定的问题 比如把一个DIV从A点移动到B点.JS为DIV.style.left=B; 但是 ...

  6. 【一】我眼中的FeatureLayer

    1.来源 MapService 或者 FeatureService(10.0后)中的一个图层 Tabel 动态空间 2.使用 符号化 首先看下FLyr的继承关系:FeatureLayer  Graph ...

  7. Google Zxing 二维码生成与解析

    生成二维码的开源项目可谓是琳琅满目,SwetakeQRCode.BarCode4j.Zxing...... 前端有JQuery-qrcode,同样能实现生成二维码. 选择Zxing的原因可能是对 Go ...

  8. 从setTimeout谈JavaScript运行机制

    从setTimeout说起 众所周知,JavaScript是单线程的编程,什么是单线程,就是说同一时间JavaScript只能执行一段代码,如果这段代码要执行很长时间,那么之后的代码只能尽情地等待它执 ...

  9. 数据契约(DataContract)及序列化指定输出字段

    服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型. 一旦声明一个类型为DataContract,那么该类型就可以被序列化在服务端和客户端之间传送,如下所 ...

  10. SQL Server output子句用法 output inserted.id 获取刚插入数据的id

    --插入数据,并返回刚刚插入的数据id INSERT INTO [soloreztest] ([name]) output inserted.id VALUES ('solorez') --执行结果: ...