IntentService 的认知与使用

作者: ingot_金果 | 来源:发表于2016-08-01 15:57 被阅读250次
    IntentService 的认知与使用

    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文件添加相应的条目。

    注意

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

    <application 
      android:icon="@drawable/icon" 
      android:label="@string/app_name">
      <service 
        android:name=".MyService" 
        android:exported="false"/>
    <application/>
    

    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 的认知与使用

        本文链接:https://www.haomeiwen.com/subject/fmnxsttx.html