文章轉載僅僅能用於非商業性質,且不能帶有虛擬貨幣、積分、註冊等附加條件。android
轉載須註明出處http://blog.csdn.net/flowingflying/以及做者@愷風Wei。app
依據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(假設有)。ide
這點和資料說的不同,資料以爲假設設置了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 /* 通常無需重寫此方法。post
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出現時的回調函數。spa
咱們需要贊成廣播接收器接收消息,第一個widget出現了。.net
咱們可以在此註冊其餘感興趣的本身定義的廣播*/
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開發相關文章