Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android handler.postDelayed vs.AlarmManager vs_Android_Handler_Broadcastreceiver_Alarmmanager_Postdelayed - Fatal编程技术网

Android handler.postDelayed vs.AlarmManager vs

Android handler.postDelayed vs.AlarmManager vs,android,handler,broadcastreceiver,alarmmanager,postdelayed,Android,Handler,Broadcastreceiver,Alarmmanager,Postdelayed,我的一个应用程序有一个小问题。它使用广播接收器来检测通话何时结束,然后执行一些小的内务管理任务。这些必须延迟几秒钟,以允许用户查看一些数据并确保呼叫日志已更新。我目前正在使用handler.postdayed用于此目的: public class CallEndReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, final Intent intent) {

我的一个应用程序有一个小问题。它使用广播接收器来检测通话何时结束,然后执行一些小的内务管理任务。这些必须延迟几秒钟,以允许用户查看一些数据并确保呼叫日志已更新。我目前正在使用handler.postdayed用于此目的:

public class CallEndReceiver extends BroadcastReceiver {

@Override
public void onReceive(final Context context, final Intent intent) {
    if (DebugFlags.LOG_OUTGOING)
        Log.v("CallState changed "
                + intent.getStringExtra(TelephonyManager.EXTRA_STATE));
    if (intent.getStringExtra(TelephonyManager.EXTRA_STATE)
            .equalsIgnoreCase(TelephonyManager.EXTRA_STATE_IDLE)) {
        SharedPreferences prefs = Utils.getPreferences(context);
        if (prefs.getBoolean("auto_cancel_notification", true)) {
            if (DebugFlags.LOG_OUTGOING)
                Log.v("Posting Handler to remove Notification ");
            final Handler mHandler = new Handler();
             final Runnable mCancelNotification = new Runnable() {
                   public void run() {
                        NotificationManager notificationMgr = (NotificationManager) context
                        .getSystemService(Service.NOTIFICATION_SERVICE);
                notificationMgr.cancel(12443);
                if (DebugFlags.LOG_OUTGOING)
                    Log.v("Removing Notification ");
                   }
                };
                mHandler.postDelayed(mCancelNotification, 4000);


        }
        final Handler updateHandler = new Handler();
         final Runnable mUpdate = new Runnable() {
               public void run() {
        if (DebugFlags.LOG_OUTGOING)
            Log.v("Starting updateService");
        Intent newBackgroundService = new Intent(context,
                CallLogUpdateService.class);
        context.startService(newBackgroundService);
               }
               };
               updateHandler.postDelayed(mUpdate, 5000);

        if (DebugFlags.TRACE_OUTGOING)
            Debug.stopMethodTracing();
        try
        {
        // Stopping old Service
        Intent backgroundService = new Intent(context,
                NetworkCheckService.class);
        context.stopService(backgroundService);
        context.unregisterReceiver(this);
        }
        catch(Exception e)
        {
            Log.e("Fehler beim Entfernen des Receivers", e);
        }
    }

}
}

现在我有一个问题,这个设置在90%的时间里都能正常工作。在大约10%的情况下,通知不会被删除。我怀疑,在消息队列处理消息/runnable之前,线程已经死亡

我现在正在考虑postDelayed的替代方案,我的选择之一显然是AlarmManager。但是,我不确定它对性能的影响或使用的资源

也许有更好的方法可以确保在线程死亡之前处理所有消息,或者有另一种方法可以延迟这两位代码的执行

多谢各位

我目前正在使用handler.postdayed用于此目的:

这不是一个好主意,假设BroadcastReceiver是由清单中的筛选器触发的

现在我有一个问题,这个设置在90%的时间里都能正常工作。在大约10%的情况下,通知不会被删除。我怀疑,在消息队列处理消息/runnable之前,线程已经死亡

更准确地说,这个过程结束了,一切都带走了

我现在正在考虑postDelayed的替代方案,我的选择之一显然是AlarmManager。但是,我不确定它对性能的影响或使用的资源

没那么糟。另一种可能是在IntentService中执行延迟的工作—通过调用startService触发—并让它在后台线程上休眠几秒钟

我目前正在使用handler.postdayed用于此目的:

这不是一个好主意,假设BroadcastReceiver是由清单中的筛选器触发的

现在我有一个问题,这个设置在90%的时间里都能正常工作。在大约10%的情况下,通知不会被删除。我怀疑,在消息队列处理消息/runnable之前,线程已经死亡

更准确地说,这个过程结束了,一切都带走了

我现在正在考虑postDelayed的替代方案,我的选择之一显然是AlarmManager。但是,我不确定它对性能的影响或使用的资源

没那么糟。另一种可能是通过调用StestService来触发您的延迟服务,并在后台线程上休眠几秒钟。除此之外,您还需要考虑API文档对OnRead方法的说明:

[…]该函数通常在其进程的主线程内调用,因此您不应该在其中执行长时间运行的操作[…]

因此,看起来一般来说,在onReceive内启动等待几次的程序不是一个好主意,即使在您的情况下,它小于10秒的限制

我对广播接收机也有类似的胆小问题。我无法得到我的结果处理,即使我的onReceive已经被调用与我正在执行的完全相同。BroadastReceiver运行的线程似乎在我的结果处理完成之前就被杀死了。我的解决方法是启动一个新的线程来执行所有的处理。

,此外,您可能需要考虑API文档对OnCube方法的说明:

[…]该函数通常在其进程的主线程内调用,因此您不应该在其中执行长时间运行的操作[…]

因此,看起来一般来说,在onReceive内启动等待几次的程序不是一个好主意,即使在您的情况下,它小于10秒的限制


我对广播接收机也有类似的胆小问题。我无法得到我的结果处理,即使我的onReceive已经被调用与我正在执行的完全相同。BroadastReceiver运行的线程似乎在我的结果处理完成之前就被杀死了。我的解决方案是启动一个新线程来执行所有处理。

AlarmManager在短时间内(如10秒)似乎无法正常工作,根据用户报告,其行为严重依赖于固件

最后,我决定在我的服务中使用Handler和Runnable

在创建处理程序时,请确保在服务类中创建它,而不是在BroadcastReceiver中,因为在上一种情况下,您将得到无法在未调用Looper.prepare的线程中创建处理程序


AlarmManager在短时间内(如10秒)似乎无法正常工作,根据用户报告,其行为严重依赖于固件

最后,我决定在中使用Handler和Runnable 我的服务

在创建处理程序时,请确保在服务类中创建它,而不是在BroadcastReceiver中,因为在上一种情况下,您将得到无法在未调用Looper.prepare的线程中创建处理程序


让我们尝试一种新的方法。使用RxJava。如果您想要并发、顺序地运行数百个这样的延迟任务,再加上异步任务,再加上同步链式异步调用等,那么原型化和管理大量线程就简单得多

首先,设置订阅服务器。记住,订阅服务器上的新建操作只应执行一次,以避免内存泄漏

// Set up a subscriber once
private Subscuber<Long> delaySubscriber = new Subscuber<Long> () {
    @Override
    public void onCompleted() {
        //Wrap up things as onCompleted is called once onNext() is over
    }
    @Override
    public void onError(Throwable e) {
        //Keep an eye open for this. If onCompleted is not called, it means onError has been called. Make sure to override this method
    }
    @Override
    public void onNext(Long aLong) {
        // aLong will be from 0 to 1000
        // Yuor code logic goes here

        // If you want to run this code just once, just add a counter and call onComplete when the counter runs the first time

    }
} 
如果您想在每一秒钟后运行一段代码,例如,您可以执行以下操作:

private Observable<Long> runThisOnInterval = Observable.interval(1000, TimeUnit.MILLISECONDS, Schedulers.computation());

让我们尝试一种新的方法。使用RxJava。如果您想要并发、顺序地运行数百个这样的延迟任务,再加上异步任务,再加上同步链式异步调用等,那么原型化和管理大量线程就简单得多

首先,设置订阅服务器。记住,订阅服务器上的新建操作只应执行一次,以避免内存泄漏

// Set up a subscriber once
private Subscuber<Long> delaySubscriber = new Subscuber<Long> () {
    @Override
    public void onCompleted() {
        //Wrap up things as onCompleted is called once onNext() is over
    }
    @Override
    public void onError(Throwable e) {
        //Keep an eye open for this. If onCompleted is not called, it means onError has been called. Make sure to override this method
    }
    @Override
    public void onNext(Long aLong) {
        // aLong will be from 0 to 1000
        // Yuor code logic goes here

        // If you want to run this code just once, just add a counter and call onComplete when the counter runs the first time

    }
} 
如果您想在每一秒钟后运行一段代码,例如,您可以执行以下操作:

private Observable<Long> runThisOnInterval = Observable.interval(1000, TimeUnit.MILLISECONDS, Schedulers.computation());

好的,正如我所想的,我只是不想浪费资源。我想我将使用AlarmManager,并为这两项任务使用单个接收器。非常感谢。好的,实施起来比我想象的容易,工作完美。再次感谢你!好的,正如我所想的,我只是不想浪费资源。我想我将使用AlarmManager,并为这两项任务使用单个接收器。非常感谢。好的,实施起来比我想象的容易,工作完美。再次感谢你!