receiver执行后台任务
2016-05-02 18:22
162 查看
一个场景:定时处理一些数据,这个过程需要较长时间,而且app未必会是前端进程。如何来实现这样的功能?
默认情况下,手机放置一段时间后,是会熄屏,然后停止cpu的。执行后台任务时,需要唤醒cpu。唤醒cpu可以使用闹钟(alarm),本文不做具体介绍,本文考虑的是接收到广播之后的处理。
Receiver接收广播的回调是在主线程中实现的,当广播所驱动的行为耗时的话,可能会引起ANR。这样就有必要创建工作线程,后台任务放在工作线程上实现。
/*******************
什么是ANR
Android Not Response
什么时候发生?
. 5s内,对用户的输入操作没有反应。
. 10s内,BroadcastReceiver没有执行完毕
********************/
简单创建Worker Thread是不可行的,这是因为当四大组件都不存在的话,进程是容易被回收的,Receiver是worker thread的执行是并行的,Receiver执行完毕之后,可能被回收。这样就不能保证工作线程正常执行。
正确的方向是Receiver启动一个后台的Service(一般是IntentService),来执行后台任务。
这样正确了吧?
还是不完全,后台任务耗时的话,cpu是会进入休眠状态的,以保持电量。所以,开发者需要手动设置wakeLock,以保持cpu在后台任务执行完毕之后释放wakelock,才进入休眠。
Android针对这种场景封装了sdk接口WakefulBroadcastReceiver,receiver的子类,接收到广播后需要创建IntentService,IntentService执行完毕之后需要释放wake lock。
其实还是封装的不太好,completeWakefulIntent 函数如果不需要开发者调用,那会更好,其实也很容易实现 (^ - ^)
默认情况下,手机放置一段时间后,是会熄屏,然后停止cpu的。执行后台任务时,需要唤醒cpu。唤醒cpu可以使用闹钟(alarm),本文不做具体介绍,本文考虑的是接收到广播之后的处理。
Receiver接收广播的回调是在主线程中实现的,当广播所驱动的行为耗时的话,可能会引起ANR。这样就有必要创建工作线程,后台任务放在工作线程上实现。
/*******************
什么是ANR
Android Not Response
什么时候发生?
. 5s内,对用户的输入操作没有反应。
. 10s内,BroadcastReceiver没有执行完毕
********************/
简单创建Worker Thread是不可行的,这是因为当四大组件都不存在的话,进程是容易被回收的,Receiver是worker thread的执行是并行的,Receiver执行完毕之后,可能被回收。这样就不能保证工作线程正常执行。
正确的方向是Receiver启动一个后台的Service(一般是IntentService),来执行后台任务。
这样正确了吧?
还是不完全,后台任务耗时的话,cpu是会进入休眠状态的,以保持电量。所以,开发者需要手动设置wakeLock,以保持cpu在后台任务执行完毕之后释放wakelock,才进入休眠。
Android针对这种场景封装了sdk接口WakefulBroadcastReceiver,receiver的子类,接收到广播后需要创建IntentService,IntentService执行完毕之后需要释放wake lock。
public class MyWakefulReceiver extends WakefulBroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // Start the service, keeping the device awake while the service is // launching. This is the Intent to deliver to the service. Intent service = new Intent(context, MyIntentService.class); startWakefulService(context, service); } }
public class MyIntentService extends IntentService { public static final int NOTIFICATION_ID = 1; private NotificationManager mNotificationManager; NotificationCompat.Builder builder; public MyIntentService() { super("MyIntentService"); } @Override protected void onHandleIntent(Intent intent) { Bundle extras = intent.getExtras(); // Do the work that requires your app to keep the CPU running. // ... // Release the wake lock provided by the WakefulBroadcastReceiver. MyWakefulReceiver.completeWakefulIntent(intent); } }
其实还是封装的不太好,completeWakefulIntent 函数如果不需要开发者调用,那会更好,其实也很容易实现 (^ - ^)
相关文章推荐
- C#线程间不能调用剪切板的解决方法
- C#线程同步的三类情景分析
- C#获取进程或线程相关信息的方法
- 简单对比C#程序中的单线程与多线程设计
- C#停止线程的方法
- C#子线程更新UI控件的方法实例总结
- C#线程队列用法实例分析
- C++使用CriticalSection实现线程同步实例
- 基于C++实现的线程休眠代码
- VB读取线程、句柄及写入内存的API代码实例
- C#网络编程基础之进程和线程详解
- C#通过Semaphore类控制线程队列的方法
- C#多线程处理多个队列数据的方法
- C#实现线程安全的简易日志记录方法
- C#中线程同步对象的方法分析
- ASP.NET线程相关配置
- 浅析linux环境下一个进程最多能有多少个线程
- 再谈JavaScript线程
- C#实现终止正在执行的线程
- Java线程编程中的主线程讲解