2012-03-04 91 views
1

我已經有一個應用程序已經widget已經有一個service它每5秒更新一次該小部件。AlarmManager生命週期和取消錯誤

這裏是我的AppWidgetProvider

public class MyWidget extends AppWidgetProvider { 

    PendingIntent service = null; 
    AlarmManager alarmManager; 

    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 

     alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
     final Intent i = new Intent(context, MyService.class); 

     if(service == null) { 
      service = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT); 
     } 

     alarmManager.setRepeating(AlarmManager.RTC, SystemClock.elapsedRealtime(), 1000*5, service); 
    } 

    @Override 
    public void onDisabled(Context context) { 
     Log.d("LogTag", "onDisabled"); 
     alarmManager.cancel(service); 
     service.cancel(); 
    } 
} 

而且我Service

public class MyService extends Service { 

    int b = 5; 

    @Override 
    public void onCreate() { super.onCreate(); } 

    public int onStartCommand(Intent intent, int flags, int startId) { 
     this.buildUpdate(); 
     return 0; 
    } 

    private void buildUpdate() { 
     Log.d("AAA", "Update is coming"); 

     RemoteViews rmViews = new RemoteViews(getPackageName(), R.layout.widget_layout); 

     rmViews.setTextViewText(R.id.hello, "Iterator: " + Integer.toString(b)); 

     ComponentName thisWidget = new ComponentName(this, MyWidget.class); 

     AppWidgetManager manager = AppWidgetManager.getInstance(this); 

     manager.updateAppWidget(thisWidget, rmViews); 

     b++; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

} 

Service和其他一切都很好。但我仍一直對所有這些東西對夫婦的問題:

  1. 什麼是對SystemClock.elapsedRealtime()這是setRepeating方法的參數?它指出什麼時候開始?

  2. 當我嘗試刪除小部件時,出現了一些錯誤(在下面),不幸的是AlarmManager仍然無法取消。我錯過了什麼?

  3. 在小部件初始化(或調用)之前,我需要做一些網絡操作。 Widget應該有一些來自服務器的數據。我應該使用AsyncTask還是什麼?

當我嘗試刪除小工具,越來越:

03-04 23:39:51.428: E/AndroidRuntime(5646): Uncaught handler: thread main exiting due to uncaught exception 
03-04 23:39:51.438: E/AndroidRuntime(5646): java.lang.RuntimeException: Unable to start receiver com.example.widget.MyWidget: java.lang.NullPointerException 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at android.app.ActivityThread.handleReceiver(ActivityThread.java:2646) 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at android.app.ActivityThread.access$3100(ActivityThread.java:119) 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1913) 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at android.os.Handler.dispatchMessage(Handler.java:99) 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at android.os.Looper.loop(Looper.java:123) 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at android.app.ActivityThread.main(ActivityThread.java:4363) 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at java.lang.reflect.Method.invokeNative(Native Method) 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at java.lang.reflect.Method.invoke(Method.java:521) 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at dalvik.system.NativeStart.main(Native Method) 
03-04 23:39:51.438: E/AndroidRuntime(5646): Caused by: java.lang.NullPointerException 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at com.example.widget.MyWidget(MyWidget.java:33) 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at android.appwidget.AppWidgetProvider.onReceive(AppWidgetProvider.java:76) 
03-04 23:39:51.438: E/AndroidRuntime(5646):  at android.app.ActivityThread.handleReceiver(ActivityThread.java:2637) 
03-04 23:39:51.438: E/AndroidRuntime(5646):  ... 10 more 

回答

2
  1. SystemClock.elapsedRealTime()你有它目前在triggerAtTime參數,這意味着任何號碼,你放在那裏是時間,你希望警報消失。 elapsedRealtime()以系統啓動後的毫秒計算,包括深度睡眠。測量可能跨越系統睡眠週期的時間間隔時應使用此時鐘。

  2. 在你的onDisabled方法中,你需要重新創建整個PendingIntent。我的猜測是,它是空的,因爲它實際上並不存在,當你打電話onDisabled,但只存在於onUpdate。因此,重新創建service變量PendingIntent完全相同的方式,然後像以前一樣調用cancel。

  3. AsyncTask s對這樣的事情很好。 AsyncTask在後臺衍生出一個託管線程,並在UI線程繼續進行時工作,然後可以在完成時更新UI線程。所以如果你有很多繁重的網絡工作,AsyncTask會處理的很好。 AsyncTask上的文檔非常有用。找到他們here。這取決於你在做什麼,有許多選擇,所以你必須在第三點解釋你的問題,以獲得更加定製的答案。

+0

謝謝。沒有嘗試AsyncTask,但得到了一些線索。 – 2012-03-05 00:02:29