Android handler.postDelayed vs.AlarmManager vs
我的一个应用程序有一个小问题。它使用广播接收器来检测通话何时结束,然后执行一些小的内务管理任务。这些必须延迟几秒钟,以允许用户查看一些数据并确保呼叫日志已更新。我目前正在使用handler.postdayed用于此目的: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) {
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,并为这两项任务使用单个接收器。非常感谢。好的,实施起来比我想象的容易,工作完美。再次感谢你!