您的位置:首页 > 其它

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。

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 函数如果不需要开发者调用,那会更好,其实也很容易实现 (^ - ^)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息