Loaders 的使用,結合Fragments

Loader的特色和使用場所

 

  1.  Loader 能夠在Activity 和Fragments 的界面下運行(本篇將結合上篇文章的Fragments的DEMO進行講述如何在Fragments 下使用Loaders)。
  2. 它能夠提供相似於AysncTask同樣的異步請求數據加載的功能,實際上它就是來源於AysncTask 的擴展並增長了不少人性化的功能,例如加載進度框、更好的控制API等。
  3. 它擁有一個相似於Windows Phone 開發的MVVM同樣的數據改變通知機制,當數據源作出改變時會及時通知。
  4. 當Cursor 發生變化時,會自動加載數據,所以並不須要再從新進行數據查詢。

Loader API 使用參考

 

  1. LoaderManager
    每個Activity 和 Fragments 只能存在一個LoaderManager,負責管理界面中的Loader。
  2. LoaderManager.LoaderCallbacks
    位於LoaderManager的子接口,提供衆多的回調接口操做Loader ,如初始化、建立、從新啓動、銷燬、結束等一系列實用接口。
  3. Loader
    與Fragments類似,是一個基礎類,能夠由用戶自行擴展適合本身的類
  4. AsyncTaskLoader
    提供了一個基於AsyncTask 工做機制的Loader,查看源碼能夠看到其繼承於Loader,而且子類LoadTask 繼承於AsyncTask<Void, Void, D>,而且實現了Runable 接口,功能十分強大。本DEMO就是基於AsyncTaskLoader篇寫。
  5. CursorLoader
    提供了一個基於AsyncTaskLoader工做機制的Loader,查看源碼能夠看到其繼承於AsyncTaskLoader,通常繼承OnQueryTextListener,可用於查詢、更改數據源做用。

Loader 詳細使用DEMO

基於上篇的Fragments 代碼,添加Loaders功能,實現加載應用程序數據到界面上,DEMO的運行效果以下:android

 

 

 核心代碼爲app

 應用程序的數據對象類:異步

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;
                }
            }
        }

    }ide

 

實現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;
            }
        }

    }this

 

實現數據源:spa

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;
        }
        

    }rest

 

在Activity 或者Fragments 裏面實現接口:
public static class DetailsFragment extends ListFragment implements OnQueryTextListener,LoaderCallbacks<List<AppEntry>>code

實現接口裏面的函數:server

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,  nullthis);

        } 

 

總結

Loader的使用分爲如下幾個步驟:

 

  1.  實現本身的異步Loader ,如本篇的AsyncTaskLoader或者CursorLoader或者本身繼承Loader,第二步須要用到這個Loader
  2. 建立數據源->public static class AppListAdapter extends ArrayAdapter<AppEntry>
  3. 在Activity 或者Fragments 上實現OnQueryTextListener,LoaderManager.LoaderCallbacks接口
  4. 在onCreateLoader裏面返回Loader,在onLoadfinished裏面作清除動做,在 onQueryTextChange或者onQueryTextSubmit改變數據源,在onCreate裏面讓Loader去執行請求數據 getLoaderManager().initLoader(0, null, this);

 

×××:/Files/TerryBlog/FragmentLoader.zip

相關文章
相關標籤/搜索