IntentService 的认知与使用

IntentService 的认知与使用_第1张图片
图片发自App

IntentService为在单一后台线程中执行任务提供了一种直接的实现方式。它可以处理一个耗时的任务并确保不影响到UI的响应性。另外IntentService的执行还不受UI生命周期的影响,以此来确保AsyncTask能够顺利运行。

但是IntentService有下面几个局限性:

  • 不可以直接和UI做交互。为了把他执行的结果体现在UI上,需要把结果返回给Activity。
  • 工作任务队列是顺序执行的,如果一个任务正在IntentService中执行,此时你再发送一个新的任务请求,这个新的任务会一直等待直到前面一个任务执行完毕才开始执行。
  • 正在执行的任务无法打断。

虽然有上面那些限制,然而在在大多数情况下,IntentService都是执行简单后台任务操作的理想选择。

1.创建IntentService

创建一个IntentService组件,需要自定义一个新的类,它继承自IntentService,并重写onHandleIntent()方法

注意

一个普通Service组件的其他回调,例如onStartCommand()会被IntentService自动调用。在IntentService中,要避免重写那些回调。

public class MyService extends IntentService { 
  @Override 
  protected void onHandleIntent(Intent workIntent) { 
  dataString = workIntent.getDataString(); 
 }}

2.在Manifest文件中定义IntentService

IntentService需要在manifest文件添加相应的条目。

注意

标签并没有包含任何intent filter。因为发送任务给IntentService的Activity需要使用显式Intent,所以不需要filter。这也意味着只有在同一个app或者其他使用同一个UserID的组件才能够访问到这个Service。


  

3.创建任务请求并发送到IntentService

一旦执行了startService(),IntentService在自己本身的onHandleIntent()方法里面开始执行这个任务,任务结束之后,会自动停止这个Service。

mServiceIntent = new Intent(getActivity(), MyService.class);
mServiceIntent.setData(Uri.parse(dataUrl));
getActivity().startService(mServiceIntent);

4.利用IntentService 发送任务状态

通过执行LocalBroadcastManager.sendBroadcast()来发送Intent。Intent被发送到任何有注册接受它的组件中。为了获取到LocalBroadcastManager的实例,可以执行getInstance()。

Intent localIntent = new Intent(Constants.BROADCAST_ACTION)     
.putExtra(Constants.EXTENDED_DATA_STATUS, status);     
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);

5.接收来自IntentService的状态广播

为了接受广播的数据对象,需要使用BroadcastReceiver的子类并实现BroadcastReceiver.onReceive()的方法,这里可以接收LocalBroadcastManager发出的广播数据。

private class ResponseReceiver extends BroadcastReceiver{ 
  DownloadStateReceiver() { } 
  public void onReceive(Context context, Intent intent) {
}}

一旦定义了BroadcastReceiver,也应该定义actions,categories与data用过滤广播。为了给系统注册这个BroadcastReceiver和IntentFilter,需要通过LocalBroadcastManager执行registerReceiver()的方法。

statusIntentFilter = new IntentFilter(Constants.ACTION_ZOOM_IMAGE);
LocalBroadcastManager.getInstance(getActivity())
.registerReceiver( mDownloadStateReceiver, mIntentFilter);

6.最后

使用LocalBroadcastManager结合IntentService其实是一种很典型高效的做法,同时也更符合OO的思想,通过广播注册与反注册的方式,对两个组件进行解耦。如果使用Handler传递到后台线程作为回调,容易带来的内存泄漏。原因是:匿名内部类对外面的Actvitiy持有引用,如果在Acitivity被销毁的时候,没有对Handler进行显式的解绑,会导致Activity无法正常销毁,这样自然就有了内存泄漏

你可能感兴趣的:(IntentService 的认知与使用)