Pro Android学习笔记(一三八):Home Screen Widgets(4):App Widget Provider

本文深入探讨了Android Widget开发中关键类BirthDayWidgetProvider的生命周期管理,包括onUpdate()、onDeleted()、onReceive()、onEnabled()和onDisabled()方法的详细解释与应用实例。同时,介绍了如何通过AppWidgetManager实现Widget的配置、删除与复用,以及Widget图标获取和自定义广播注册等核心功能。

文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处http://blog.youkuaiyun.com/flowingflying/以及作者@恺风Wei

根据widget定义,我们App Widget Provider的Java类为BirthDayWidgetProvider,这个类用于管理Widget的各个生命周期。

public class BirthDayWidgetProvider extends AppWidgetProvider{
    private static String tag = "BirthDayWidgetProvider";

    @Override /* 在3种情况下会调用OnUpdate()。onUpdate()是在main线程中进行,因此如果处理需要花费时间多于10秒,处理应在service中完成。
(1)在时间间隔到时调用,时间间隔在widget定义的android:updatePeriodMillis中设置;
(2)用户拖拽到主页,widget实例生成。
无论有没有设置Configure activity,我们在Android4.4的测试中,当用户拖拽图片至主页时,widget实例生成,会触发onUpdate(),然后再显示activity(如果有)。这点和资料说的不一样,资料认为如果设置了Configure acitivity,就不会在一开始调用onUpdate(),而实验显示当实例生成(包括创建和重启时恢复),都会先调用onUpate()。在本例,由于此时在preference尚未有相关数据,创建实例时不能有效进行数据设置。
(3)机器重启,实例在主页上显示,会再次调用onUpdate()*/
   public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
        Log.d(tag,"onUpdate() called. 有 " + appWidgetIds.length + "个widgets");   
        for(int i = 0 ; i< appWidgetIds.length; i ++){
            Log.d(tag,"update widget ID " + appWidgetIds[i]);
            BirthDayStoreData.updateAppWidget(context, appWidgetIds[i]);
        }
    }

    @Override  /* 某个/些widget从主页中删除,在此删除该widget的相关数据  */
    public void onDeleted(Context context, int[] appWidgetIds) { 
        Log.d(tag,"onDeleted() called"); 
        for(int i = 0 ; i < appWidgetIds.length; i ++){
            Log.d(tag,"delete widget " + appWidgetIds[i] + " data");
            BirthDayStoreData.removeData(context, appWidgetIds[i]);
        }
        BirthDayStoreData.showData(context);
    }
   
    @Override /* 一般无需重写此方法。App Widget provider本质是receiver,在此可以跟踪收到什么消息,这些消息包括AppWidgetManager.ACTION_APPWIDGET_DELETED/UPDATE/ENABLED/DISABLED,super.onReceiver()会根据消息类型触发不同的回调函数。如果采用AlarmManager或者自定义的广播,可以再次进行处理。 */
    public void onReceive(Context context, Intent intent) {
 
        Log.i(tag,"onReceive() : " + intent); 
        super.onReceive(context, intent); 
    }     

    @Override  /* 表明至少有一个widget实例被拖到主页上,即当第一个widget出现时的回调函数。我们需要允许广播接收器接收消息,第一个widget出现了。我们可以在此注册其它感兴趣的自定义的广播*/
    public void onEnabled(Context context) {
 
        Log.d(tag,"onEnabled() called, context " + context.toString());          
        // setComponentEnabledSetting相当于在AndriodMenifest.xml文件中队组件设置android:enabled为true|false。此处是对receiver进行设置,如果true,则允许进行监听,包括开机重启。 
        PackageManager pm = context.getPackageManager();
      /*使用new ComponentName("cn.wei.flowingflying.testwidget",".BirthDayWidgetProvider")出现不明原因错误,
        * 可对类名采用完全名称,及new ComponentName("cn.wei.flowingflying.testwidget",
        *                               "cn.wei.flowingflying.testwidget.BirthDayWidgetProvider"),
        * 或通过系统获取组件名的方式new ComponentName(context, getClass())*/

        pm.setComponentEnabledSetting(new ComponentName(context, getClass()),
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);        
    }

    @Override  /*最后一个widget已从主页中删除,在此,确保删除所有配置数据,无需进行广播监听,色织enabled=false,如果有注册的自定义广播,在此unregister */
    public void onDisabled(Context context) { 
        BirthDayStoreData.removeAllData(context);
        PackageManager pm = context.getPackageManager();
        pm.setComponentEnabledSetting(new ComponentName(context, getClass()),
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);         
    }

}

如果主页没有实例,新实例的生成触发顺序为:onEnabled() –>onUpdate() –>Configure Activity,头两个顺序可能会出现变化。估计是AppWidgetManager的异步处理导致广播消息出现的先后顺序问题。如果已经有实例,新实例生成触发顺序为onUpdate() –> Configure activity。配置后,等待定义的时间间隔,进行定期触发onUpdate()。

机器重启 onEnabled() –>onUpdate() –> onUpdate(),同样头两个顺序可能会交换,此后,等待widget定义的时间间隔,进行定期触发onUpdate()。

如果我们更新或重装apk,实例并不会被删除,会触发onUpdate()。

补充:Widget图标

Widget在widget列表中显示的通常都是widget的外貌,Android模拟器有一个应用Widget Preview可以帮助我们获取widget的外观图标,如下:

通过adb pull将存贮在模拟器SD卡Download路径下的preview图片获取,作为列表显示图标。


小例子代码在:Pro Android学习:widget小例子 

相关链接:我的Android开发相关文章

物联网通信协议测试是保障各类设备间实现可靠数据交互的核心环节。在众多适用于物联网的通信协议中,MQTT(消息队列遥测传输)以其设计简洁与低能耗的优势,获得了广泛应用。为确保MQTT客户端与服务端的实现严格遵循既定标准,并具备良好的互操作性,实施系统化的测试验证至关重要。 为此,采用TTCN-3(树表结合表示法第3版)这一国际标准化测试语言构建的自动化测试框架被引入。该语言擅长表达复杂的测试逻辑与数据结构,同时保持了代码的清晰度与可维护性。基于此框架开发的MQTT协议一致性验证套件,旨在自动化地检验MQTT实现是否完全符合协议规范,并验证其与Eclipse基金会及欧洲电信标准化协会(ETSI)所发布的相关标准的兼容性。这两个组织在物联网通信领域具有广泛影响力,其标准常被视为行业重要参考。 MQTT协议本身存在多个迭代版本,例如3.1、3.1.1以及功能更为丰富的5.0版。一套完备的测试工具必须能够覆盖对这些不同版本的验证,以确保基于各版本开发的设备与应用均能满足一致的质量与可靠性要求,这对于物联网生态的长期稳定运行具有基础性意义。 本资源包内包含核心测试框架文件、一份概述性介绍文档以及一份附加资源文档。这些材料共同提供了关于测试套件功能、应用方法及可能包含的扩展工具或示例的详细信息,旨在协助用户快速理解并部署该测试解决方案。 综上所述,一个基于TTCN-3的高效自动化测试框架,为执行全面、标准的MQTT协议一致性验证提供了理想的技术路径。通过此类专业测试套件,开发人员能够有效确保其MQTT实现的规范符合性与系统兼容性,从而为构建稳定、安全的物联网通信环境奠定坚实基础。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值