BroadcastReceiver处理耗时操作
来源:互联网 发布:手机变音软件 编辑:程序博客网 时间:2024/06/05 08:40
Long-Running Receivers and Services
broadcast receiver is unlikely to take more than ten seconds. As it turns out, the
problem space becomes a bit complicated if we want to perform tasks that take longer than ten seconds.
A broadcast receiver, like other components of an An droid process,
runs on the main thread.
Holding up the code in a broadcast receiver will hold up the main
thread and will result in ANR.
The time limit on a broadcast receiver is ten seconds compared to five
seconds for an activity. It is a touch of a reprieve, but the limit is still
there.
The process hosting the broadcast receiver will start and terminate
along with the broadcast receiver execution. Hence the process will
not stick around after the broadcast receiver’s onReceive() method
returns. Of course, this is assumi ng that the process contains only the
broadcast receiver. If the process contains other components, such as
activities or services, that are alr eady running, then the lifetime of the
process takes these component life cycles into account as well.
Unlike a service process, a broadcast receiver process will not get restarted.
If a broadcast receiver were to start a separate thread and return to
the main thread, Android will assume that the work is complete and
will shut down the process even if there are threads running, bringing
those threads to abrupt stop.
Android acquires a partial wake lock when invoking a broadcast
service and releases it when it re turns from the service in the main
thread. A wake lock is a mechanism and an API class available in the
SDK to keep the device from going to sleep or wake it up if it is already asleep.
broadcast event?
Long-Running Broadcast Receiver Protocol
The answer lies in resolving the following:
We will clearly need a separate thread so that the main thread can get
back and avoid ANR messages.
To stop Android from killing the process and hence the worker thread,
we need to tell Android that this process contains a component, such
as a service, with a life cycle. So we need to create or start that
service. The service itself cannot directly do the work for more than
five seconds because that happens on the main thread, so the service
needs to start a worker thread and let the main thread go.
For the duration of the worker thread’s execution, we need to hold on
to the partial wake lock so that the device won’t go to sleep. A partial
wake lock will allow the device to run code without turning on the
screen and so on, which allows for longer battery life.
The partial wake lock must be obtained in the main line code of the
receiver; otherwise, it will be too late. For example, you cannot do this
in the service, because it may be too late between the startService()
being issued by the broadcast receiver and the onStartCommand() of a
service that begins execution.
Because we are creating a service, the service itself can be brought
down and brought back up because of low-memory conditions. If this
happens, we need to acquire the wake lock again.
When the worker thread started by the onStartCommand() method of
the service completes its work, it needs to tell the service to stop so
that it can be put to bed and not brought back to life by Android.
It is also possible that more than one broadcast event can occur.
Given that, we need to be cautious about how many worker threads
we need to spawn.
Given these facts, the recommended protocol for extending the life of a broadcast
receiver is as follows:
1. Get a (static) partial wake lock in the onReceive() method of the
broadcast receiver. The partial wake lock needs to be static to allow
communication between the broadcast receiver and the service. There
is no other way of passing a reference of the wake lock to the service,
as the service is invoked through a default constructor that takes no
parameters.
2. Start a local service so that the process won’t be killed.
CHAPTER 19: Broadcast Receivers and Long-Running Services 516
3. In the service, start a worker thread to do the work. Do not do the work
in the onStart() method of the service. If you do, you are basically
holding up the main thread again.
4. When the worker thread is done, tell the service to stop itself either
directly or through a handler.
5. Have the service turn off the static wake lock. To repeat, a static wake
lock is the only way to communicate between a service and its invoker,
in this case the broadcast service, because there is no way to pass a
wake lock reference to the service.
You can read the book for more info, the following is an example:
public abstract class ALongRunningNonStickyBroadcastService extends IntentService { public static String tag = "ALongRunningBroadcastService"; protected abstract void handleBroadcastIntent(Intent broadcastIntent); public ALongRunningNonStickyBroadcastService(String name){ super(name); } /* * This method can be invoked under two circumstances * 1. When a broadcast receiver issues a "startService" * 2. when android restarts it due to pending "startService" intents. * * In case 1, the broadcast receiver has already * setup the "lightedgreenroom". * * In case 2, we need to do the same. */ @Override public void onCreate() { super.onCreate(); //Set up the green room //The setup is capable of getting called multiple times. LightedGreenRoom.setup(this.getApplicationContext()); //It is possible that more than one service //of this type is running. //Knowing the number will allow us to clean up //the locks in ondestroy. LightedGreenRoom.s_registerClient(); } @Override public int onStartCommand(Intent intent, int flag, int startId) { //Call the IntentService "onstart" super.onStart(intent, startId); //Tell the green room there is a visitor LightedGreenRoom.s_enter(); //mark this as non sticky //Means: Don't restart the service if there are no //pending intents. return Service.START_NOT_STICKY; } /* * Note that this method call runs * in a secondary thread setup by the IntentService. * * Override this method from IntentService. * Retrieve the original broadcast intent. * Call the derived class to handle the broadcast intent. * finally tell the lighted room that you are leaving. * if this is the last visitor then the lock * will be released. */ @Override final protected void onHandleIntent(Intent intent) { try { Intent broadcastIntent = intent.getParcelableExtra("original_intent"); handleBroadcastIntent(broadcastIntent); } finally { LightedGreenRoom.s_leave(); } } /* * If Android reclaims this process, * this method will release the lock * irrespective of how many visitors there are. */ @Override public void onDestroy() { super.onDestroy(); LightedGreenRoom.s_unRegisterClient(); } }
- BroadcastReceiver处理耗时操作
- BroadCastReceiver中耗时操作导致ANR
- BroadCastReceiver中耗时操作导致ANR
- 如何在 BroadcastReceiver 中执行耗时操作?
- Swift-处理耗时操作
- 回调 处理耗时操作
- IntentService可处理耗时操作
- android中的broadcastreceiver不可以做耗时操作
- ProgressDialog和Thread结合处理耗时操作
- ProcessDialog结合Thread处理耗时操作
- AsyncTask 使用后台线程处理耗时操作
- UI系统中的耗时操作处理
- iOS对耗时操作的处理方法
- MFC 处理耗时操作的一种办法
- ProcessDialog结合Thread处理耗时操作
- iOS处理耗时操作一种简单方法
- django 耗时操作处理办法 celery
- 在BroadCastReceiver的onReceive方法中执行耗时操作的正确姿势
- VIM用户手册 For Vim version 7.3. *usr_20.txt*
- HDOJ 2571 命运
- curl 转自 http://blog.chinaunix.net/uid-22655387-id-3283161.html
- 装饰模式(Decorator)
- VIM用户手册 For Vim version 7.3. *usr_21.txt*
- BroadcastReceiver处理耗时操作
- VIM用户手册 For Vim version 7.3. *usr_22.txt*
- “压缩感知” 之 “Hello World”
- dfgallery 2.0 安装配置
- ACE日志系统之本机日志系统的多文件实现
- 后缀数组
- OpenCV中Mat与IplImage和CvMat类型之间的相互转换
- MzTreeView应用
- HDU1702