Loader 小记

装载器从android3.0开始引进。它使得在activityfragment中异步加载数据变得简单。从谷歌文档中可以看到,它具有以下四个特性:

1. 他们对每个 activity 和 fragment 都有效。(因为 loader 对象需要 LoaderManager 来管理,而在 activity 和 fragment 中能获取到 LoaderManager 对象。其实 fragment 拿到的 LoaderManager 对象是 其所绑定的 activity 中的 LoaderManager 对象)。

2. 他们提供了 异步加载数据 的能力

3. 他们监视数据源,并在数据源改变时传递新的结果。

4. 在其所在的 activity 或者 fragment 由于设备配置改变而被重新启动后,它可以自动链接到之前使用的加载器,从而不需要重新查询结果。


LoaderManager 中的 initLoader() 方法用来初始化一个 loader。在这个方法中,首先根据传入的参数,判断这个 id 对应的loader是否已经存在并且有效,如果存在并有效,那么只是给已存在的loader对象换一个回调函数;否则创建一个新的loader对象,此时调用传入的回调函数中的 onCreateLoader 方法。获取到loader对象之后,判断当前的 activity 是否可见(started),可见就启动这个loader,让它开始加载数据(因为 LoaderManager 会在 activity 进行到 onStart 方法的时候,自动启动所有的loader开始加载数据)。所谓的“让它开始加载数据”,只不过是调用 loader 对象的 startLoading 方法而已。在这个方法中,设置了三个布尔量的值,然后调用了 onStartLoading() 方法来加载数据。在我们自定义 loader 的时候,继承的 AsyncTaskLoader 类中的 onStartLoading() 方法只有一个空方法体。所以此时我们一定要覆写 onStartLoading() 方法,并且在其中调用 forceLoad() 方法来强制加载数据。


loader 的回调函数中的 onLoaderReset() 方法让我难以理解,所以研究了一下。发现只有在 destroy 一个 loader 的时候才有可能调用 onLoaderReset 这个方法,下面是贴一段代码大家一看就明白了(代码摘自android源码 LoaderManager.java 中)。

void destroy() {
            if (DEBUG) Log.v(TAG, "  Destroying: " + this);
            mDestroyed = true;
            boolean needReset = mDeliveredData;
            mDeliveredData = false;
            if (mCallbacks != null && mLoader != null && mHaveData && needReset) {
                if (DEBUG) Log.v(TAG, "  Reseting: " + this);
                String lastBecause = null;
                if (mActivity != null) {
                    lastBecause = mActivity.mFragments.mNoTransactionsBecause;
                    mActivity.mFragments.mNoTransactionsBecause = "onLoaderReset";
                }
                try {
                    mCallbacks.onLoaderReset(mLoader);
                } finally {
                    if (mActivity != null) {
                        mActivity.mFragments.mNoTransactionsBecause = lastBecause;
                    }
                }
            }
            mCallbacks = null;
            mData = null;
            mHaveData = false;
            if (mLoader != null) {
                if (mListenerRegistered) {
                    mListenerRegistered = false;
                    mLoader.unregisterListener(this);
                    mLoader.unregisterOnLoadCanceledListener(this);
                }
                mLoader.reset();
            }
            if (mPendingLoader != null) {
                mPendingLoader.destroy();
            }
        }
所以一般在 onLoaderReset 方法中释放该 loader 中的数据。从以上代码还可以看到,在这里还调用了 mLoader.reset 方法,这个方法也会引起一个方法 onReset() 调用(属于 loader 的方法)。这个我们在自定义 loader 时也用得到,同样处理释放相关的操作。


loader还有一个操作是 restart,这个就是“ 重新创建一个使用这个id的loader ”。  


关于自定义 Loader,大家可以参考下 Api Demos 中的 App --> Loader --> Custom 。

以下是我看例子总结的一些重点:

1. 自定义的数据集(在例子中就是 AppListAdapter ),要有一个 public 的方法来设置数据;

2. 自定义的 loader 要记得自己驱动 加载数据 和 释放数据的过程;

3. 自定义的 loader 要自己实现对数据源的监控和实时更新自己的数据(在例子中是通过定义 BroadCastReceiver 来实现的)。

4. 以内部类的形式来实现自定义 loader 的话,该内部类必须是 static 的,否则会抛出异常,使程序崩溃。

5. loader 的回调方法都是在 初始化该loader的方法所在的线程中 执行的,加载数据的过程是在其他线程。


AsyncTaskLoader 类中的 setUpdateThrottle 方法可以设置两次 load 之间的最小时间间隔。

1. 用户与身体信息管理模块 用户信息管理: 注册登录:支持手机号 / 邮箱注册,密码加密存储,提供第三方快捷登录(模拟) 个人资料:记录基本信息(姓名、年龄、性别、身高、体重、职业) 健康目标:用户设置目标(如 “减重 5kg”“增肌”“维持健康”)及期望周期 身体状态跟踪: 体重记录:定期录入体重数据,生成体重变化曲线(折线图) 身体指标:记录 BMI(自动计算)、体脂率(可选)、基础代谢率(根据身高体重估算) 健康状况:用户可填写特殊情况(如糖尿病、过敏食物、素食偏好),系统据此调整推荐 2. 膳食记录与食物数据库模块 食物数据库: 基础信息:包含常见食物(如米饭、鸡蛋、牛肉)的名称、类别(主食 / 肉类 / 蔬菜等)、每份重量 营养成分:记录每 100g 食物的热量(kcal)、蛋白质、脂肪、碳水化合物、维生素、矿物质含量 数据库维护:管理员可添加新食物、更新营养数据,支持按名称 / 类别检索 膳食记录功能: 快速记录:用户选择食物、输入食用量(克 / 份),系统自动计算摄入的营养成分 餐次分类:按早餐 / 午餐 / 晚餐 / 加餐分类记录,支持上传餐食照片(可选) 批量操作:提供常见套餐模板(如 “三明治 + 牛奶”),一键添加到记录 历史记录:按日期查看过往膳食记录,支持编辑 / 删除错误记录 3. 营养分析模块 每日营养摄入分析: 核心指标计算:统计当日摄入的总热量、蛋白质 / 脂肪 / 碳水化合物占比(按每日推荐量对比) 微量营养素分析:检查维生素(如维生素 C、钙、铁)的摄入是否达标 平衡评估:生成 “营养平衡度” 评分(0-100 分),指出摄入过剩或不足的营养素 趋势分析: 周 / 月营养趋势:用折线图展示近 7 天 / 30 天的热量、三大营养素摄入变化 对比分析:将实际摄入与推荐量对比(如 “蛋白质摄入仅达到推荐量的 70%”) 目标达成率:针对健
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值