zoukankan      html  css  js  c++  java
  • Pro Android学习笔记(一三八):Home Screen Widgets(4):App Widget Provider

    文章转载仅仅能用于非商业性质,且不能带有虚拟货币、积分、注冊等附加条件。

    转载须注明出处http://blog.csdn.net/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开发相关文章

  • 相关阅读:
    C# Invoke 和 BeginInvoke 的的区别
    ArcGIS API For JS 中设置图层显示的方法(ArcGISDynamicMapServiceLayer)setVisibleLayers(ids, doNotRefresh?)介绍
    OpenLayer学习之矢量地图
    Python爬去百思不得其解的图片(VS2017)
    .NET面试试题
    arcgis for javascript 鼠标移到对象上面则置亮并弹出气泡
    ASP.NET MVC 中IBaseDal接口的封装
    ASP.NET中MemcacheHelper封装
    ASP.NET验证码的封装和使用
    Self-Paced Training (2)
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/7402750.html
Copyright © 2011-2022 走看看