Android之Loader加载功能

  Loaders在Android 3.0版本后引入。Loaders使异步加载数据更加容易。Loaders有如下的特性:
 1.它们适用于任何Activity和Fragment;
     2.  它们提供了异步加载数据的机制;
     3.  它们检测数据源,当数据源内容改变时它们能够传递新的结果;
     4. 当配置改变后需要重新创建时,它们会重新连接到最后一个loader的游标。这样,它们不需要重新查询它们的数据。
      根据官方API DEMO中的LoaderCustom类整理的Demo,功能是通过Loader异步加载手机中所有的APP应用。
/**
 * 展示手机中所有应用程序列表的页面
 * 
 * @description:
 * @author ldm
 * @date 2016-5-5 上午9:26:28
 */
public class AppsActivity extends Activity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FragmentManager fm = getFragmentManager();
        // 系统定义的此Fragment的id为android.R.id.content
        if (fm.findFragmentById(android.R.id.content) == null) {
            AppListFragment list = new AppListFragment();
            // 添加 Fragment
            fm.beginTransaction().add(android.R.id.content, list).commit();
        }

    }
}

/**
* SearchView.OnQueryTextListener:的实现在用户查询发生改变时重启了装载器,
* 装载器于是需重启从而能使用新的搜索过虑来进行一次新的查询.
* SearchView.OnCloseListener:当用户关闭SearchView时触发的回调函数
* LoaderManager:是加载器的管理器,一个LoaderManager可以管理一个或多个Loader
* ,一个Activity或者Fragment只能有一个LoadManager。 LoaderManager管理Loader的初始化,重启和销毁操作。
* LoaderManager.LoaderCallBacks:用来向客户返回数据的方式
*
* @description:
* @author ldm
* @date 2016-5-5 上午9:29:33
*/
public class AppListFragment extends ListFragment implements
OnQueryTextListener, OnCloseListener,
LoaderManager.LoaderCallbacks

**
 * 在Android3.0中引入了AsyncTaskLoader装载器功能类,这使它很容易在Activity或Fragment中使用异步的方式加载数据。
 * 装载器的特点如下:
 * 
 * 1. 装载器对于每个Activity和Fagment都是有效的;
 * 
 * 2. 装载器提供异步数据加载的能力;
 * 
 * 3. 装载器监视数据资源并且当内容改变时发送新的结果;
 * 
 * 4. 在配置改变后重建的时候,装载器自动的重连最后的装载器游标,因此,不需要重新查询数据。
 * 
 * @description:
 * @author ldm
 * @date 2016-5-4 下午6:06:20
 */
public class AppListLoader extends AsyncTaskLoader<List<AppEntry>> {
    private InterestingConfigChanges mLastConfig = new InterestingConfigChanges();
    public PackageManager mPm;
    private List<AppEntry> mApps;
    private PackageIntentReceiver mPackageObserver;

    public AppListLoader(Context context) {
        super(context);
        // 初始化包管理PackageManager对象
        mPm = getContext().getPackageManager();
    }

    /**
     * 根据指定标志排序
     */
    private static final Comparator<AppEntry> ALPHA_COMPARATOR = new Comparator<AppEntry>() {
        private final Collator sCollator = Collator.getInstance();

        @Override
        public int compare(AppEntry object1, AppEntry object2) {
            return sCollator.compare(object1.getLabel(), object2.getLabel());
        }
    };

    /**
     * 这是Loader的核心方法,必须重载,后台运行。在这里头实现加载数据的功能
     */
    @Override
    public List<AppEntry> loadInBackground() {
        // GET_UNINSTALLED_PACKAGES代表已删除,但还有安装目录的
        // GET_DISABLED_COMPONENTS获取所有组件
        List<ApplicationInfo> apps = mPm
                .getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES
                        | PackageManager.GET_DISABLED_COMPONENTS);
        if (apps == null) {
            apps = new ArrayList<ApplicationInfo>();
        }

        final Context context = getContext();

        List<AppEntry> entries = new ArrayList<AppEntry>(apps.size());
        for (int i = 0; i < apps.size(); i++) {
            AppEntry entry = new AppEntry(this, apps.get(i));
            entry.loadLabel(context);
            entries.add(entry);
        }
        // 排序
        Collections.sort(entries, ALPHA_COMPARATOR);
        // 返回数据结果
        return entries;
    }

    /**
     * 将结果传递给已注册的监听器们。
     */
    @Override
    public void deliverResult(List<AppEntry> apps) {
        if (isReset()) {
            if (apps != null) {
                onReleaseResources(apps);
            }
        }
        List<AppEntry> oldApps = mApps;
        mApps = apps;

        if (isStarted()) {
            super.deliverResult(apps);
        }

        if (oldApps != null) {
            onReleaseResources(oldApps);
        }
    }

    /**
     * 开始Loader数据
     */
    @Override
    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();
        }
    }

    /**
     * 停止Loader数据
     */
    @Override
    protected void onStopLoading() {
        // 取消当前的加载任务
        cancelLoad();
    }

    @Override
    public void onCanceled(List<AppEntry> apps) {
        super.onCanceled(apps);

        onReleaseResources(apps);
    }

    @Override
    protected void onReset() {
        super.onReset();
        // 停止加载
        onStopLoading();
        // 释放资源
        if (mApps != null) {
            onReleaseResources(mApps);
            mApps = null;
        }
        if (mPackageObserver != null) {
            getContext().unregisterReceiver(mPackageObserver);
            mPackageObserver = null;
        }
    }

    protected void onReleaseResources(List<AppEntry> apps) {
    }
}
只贴了三个类的代码,说明及注释我习惯放在代码中,Demo项目参考:http://download.csdn.net/detail/true100/9510613 
开源代码:https://github.com/ldm520/ANDROID_API_DEMOS
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值