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會停止。以後這種問題一定要多加註意!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章