android - AlarmManager 生命周期和取消错误

标签 android alarmmanager

我有一个应用程序,它已经有一个widget 并且有一个service 每 5 秒更新一次那个 widget。

这是我的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();
    }
}

还有我的服务:

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. 我需要在小部件初始化(或调用)之前执行一些网络操作。小部件应该有一些来自服务器的数据。我应该使用 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

最佳答案

  1. SystemClock.elapsedRealTime() 当前在 triggerAtTime 参数中,这意味着您输入的任何数字都是您想要的时间警报响起。 elapsedRealtime() 以系统启动后的毫秒数计算,包括深度 sleep 。在测量可能跨越系统休眠期的时间间隔时,应使用此时钟。

  2. 在您的onDisabled 方法中,您需要重新创建整个PendingIntent。我猜它在那里是空的,因为当你调用 onDisabled 时它实际上并不存在,而只存在于 onUpdate 中。因此,以与之前完全相同的方式重新创建 service 变量 PendingIntent,然后像现在一样对其调用 cancel。

  3. AsyncTask 非常适合此类事情。 AsyncTask 在后台生成一个托管线程,并在 UI 线程继续运行时工作,然后可以在完成后更新 UI 线程。因此,如果您有大量繁重的网络工作要做,AsyncTask 可以很好地处理。 AsyncTask 上的文档非常有用。找到他们 here .根据您的工作,有多种选择,因此您必须更详细地解释第三点的问题,以获得更有针对性的答案。

关于android - AlarmManager 生命周期和取消错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9559194/

相关文章:

android - 使用 AlarmReceiver 和 OnBootReceiver 为 android 应用程序设置闹钟

android - 无法关闭/隐藏 Android 5.0 Lollipop 上的警报图标

android - 如何避免超过闹钟时间后触发闹钟?

java - 无法发送自动短信

android - 如何在 Genymotion 中重启安卓设备模拟器

java - 如何从单击项打开 ListView ?

android - 绑定(bind)识别服务失败

android - 使用 AlarmManager 从 BroadcastReceiver 启动服务

java - java中int数组的声明与定义分开

android - ORMLite - 从两个表中查找结果的并集