• Android Loader使用详解


    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

  • 相关阅读:
    LeetCode K Closest Points to Origin
    LeetCode Largest Number
    LeetCode Sort List
    LeetCode Sort Colors
    LeetCode Matrix Cells in Distance Order
    spring定时任务的几种实现方式
    maven构建这么慢,怎么改变?
    序列化框架性能对比(kryo、hessian、java、protostuff)
    java的静态方法的使用
    jvm的可见性的理解
  • 原文地址:https://www.cnblogs.com/wytiger/p/5336502.html
Copyright © 2020-2023  润新知