App Widget深入+Android Studio 真机断点调试注意事项

最近几天一直想做一个类似于时钟的App Widget的效果,然后就开始设计,看了google 的有关文档,按照步骤先弄出了一个没有任何实际效果的widget,

又了解到相关的AppWidgetProvider其实是一个广播接收者,可以接收特定的广播事件,大致有以下几个:

1.AppWidgetManager.ACTION_APPWIDGET_UPDATE,对应调用onUpdate()方法;

2.AppWidgetManager.ACTION_APPWIDGET_DELETED,对用调用onDeleted()方法;

3.AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED,对用调用onAppWidgetOptionsChanged()方法;

4.AppWidgetManager.ACTION_APPWIDGET_ENABLED,对用调用onEnabled()方法;

5.AppWidgetManager.ACTION_APPWIDGET_DISABLED,对用调用onDisabled()方法;

具体实现过程:其实每次在调用不同生命周期方法时,都会先调用onReceive()方法,因为它是广播接收者,在onReceive()方法中根据开启广播的意图的action来调用相应的方法,附onReceive()方法的源码:

public void onReceive(Context context, Intent intent) {
        // Protect against rogue update broadcasts (not really a security issue,
        // just filter bad broacasts out so subclasses are less likely to crash).
        String action = intent.getAction();
        if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
            Bundle extras = intent.getExtras();
            if (extras != null) {
                int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
                if (appWidgetIds != null && appWidgetIds.length > 0) {
                    this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
                }
            }
        } else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
            Bundle extras = intent.getExtras();
            if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
                final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
                this.onDeleted(context, new int[] { appWidgetId });
            }
        } else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)) {
            Bundle extras = intent.getExtras();
            if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)
                    && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS)) {
                int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
                Bundle widgetExtras = extras.getBundle(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);
                this.onAppWidgetOptionsChanged(context, AppWidgetManager.getInstance(context),
                        appWidgetId, widgetExtras);
            }
        } else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
            this.onEnabled(context);
        } else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
            this.onDisabled(context);
        } else if (AppWidgetManager.ACTION_APPWIDGET_RESTORED.equals(action)) {
            Bundle extras = intent.getExtras();
            if (extras != null) {
                int[] oldIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);
                int[] newIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
                if (oldIds != null && oldIds.length > 0) {
                    this.onRestored(context, oldIds, newIds);
                    this.onUpdate(context, AppWidgetManager.getInstance(context), newIds);
                }
            }
        }
    }

另外在调试该应用的时候,出现了一个问题困扰我老半天,我在onEnable()方法中添加了断点,然后开启真机调试,但是一进入调试界面,在android studio 的调试视图上,当程序运行到断点时,过几秒会自动退出调试过程,并且显示“frame is not available”,就算重启软件,重新连接手机也是同样的问提,简直打击我的积极性。而后我在stackoverflow上提出了这个问题,经过大神的不懈指导,终于发现了问题所在。


因为AppWidgetProvider是一个广播接受者, 所以当它的onEnabled()方法调用时,是因为收到了相应的广播,又因为广播接收者是在主线程中处理广播事件,所以当一个广播10秒钟之内没有得到响应的话,就会出现ANR异常,因为我在onEnabled()方法中加了断点,程序阻塞在这里,这样这个广播事件没有得到及时的相应,故程序会崩溃,故而debugger会停止。以后这种问题一定要多加注意!


你可能感兴趣的:(Google,Android,Developer,文档学习)