如何使用IntentService

参考 https://developer.android.google.cn/reference/android/app/IntentService.html

IntentService定义

  • IntentService继承与Service,用来处理异步请求。客户端可以通过startService(Intent)方法传递请求给IntentService。IntentService在onCreate()方法中通过HandlerThread单独开启一个线程来依次处理所有Intent请求对象所对应的任务,这样以免事务处理阻塞主线程(ANR)。执行完所一个Intent请求对象所对应的工作之后,如果没有新的Intent请求达到,则自动停止Service;否则执行下一个Intent请求所对应的任务。

  • IntentService在处理事务时,还是采用的Handler方式,创建一个名叫ServiceHandler的内部Handler,并把它直接绑定到HandlerThread所对应的子线程。 ServiceHandler把处理一个intent所对应的事务都封装到叫做onHandleIntent的抽象方法;因此我们直接实现抽象方法onHandleIntent,再在里面根据Intent的不同进行不同的事务处理就可以了。 另外,IntentService默认实现了onbind()方法,返回值为null。

  • 源码

      public abstract class IntentService extends Service {
          private volatile Looper mServiceLooper;
          private volatile ServiceHandler mServiceHandler;
          private String mName;
          private boolean mRedelivery;
          
          // 内部Handler处理
          private final class ServiceHandler extends Handler {
              public ServiceHandler(Looper looper) {
                  super(looper);
              }
      
              @Override
              public void handleMessage(Message msg) {
                  onHandleIntent((Intent)msg.obj);
                  // 关闭当前Service
                  stopSelf(msg.arg1);
              }
          }
      
         
          public IntentService(String name) {
              super();
              mName = name;e;     
          }
       
        
          public void setIntentRedelivery(boolean enabled) {
              mRedelivery = enabled;
          }
      
          @Override
          public void onCreate() {
              super.onCreate();
              HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
              thread.start();
      
              mServiceLooper = thread.getLooper();
              mServiceHandler = new ServiceHandler(mServiceLooper);
          }
      
          @Override
          public void onStart(@Nullable Intent intent, int startId) {
              // 发送消息(Intent)
              Message msg = mServiceHandler.obtainMessage();
              msg.arg1 = startId;
              msg.obj = intent;
              mServiceHandler.sendMessage(msg);
          }
      
          @Override
          public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
              onStart(intent, startId);
              return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
          }
      
          @Override
          public void onDestroy() {
              mServiceLooper.quit();
          }
      
          @Override
          @Nullable
          public IBinder onBind(Intent intent) {
              return null;
          }
    
          // 需要覆盖该方法进行一步处理
          @WorkerThread
          protected abstract void onHandleIntent(@Nullable Intent intent);
      }
    

实现方式

  • 定义一个TestIntentService继承IntentService

      public class TestIntentService extends IntentService {
      
          // 注意构造函数参数为空,这个字符串就是WorkThread的名字
          public TestIntentService() {
              super("TestIntentService");
          }
      
          @Override
          public void onCreate() {
              Log.d("TIS","onCreate()");
              super.onCreate();
          }
    
          @Override
          public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
              Log.d("TIS","onStartCommand()");
              return super.onStartCommand(intent, flags, startId);
          }
      
          @Override
          public void onDestroy() {
              super.onDestroy();
              Log.d("TIS","onDestroy()");
          }
      
          @Override
          protected void onHandleIntent(@Nullable Intent intent) {
              if (intent != null) {
                  int taskId = intent.getIntExtra("taskId", -1);
                  // 依次处理Intent请求
                  switch (taskId) {
                      case 0:
                          Log.d("TIS","handle task0");
                          break;
                      case 1:
                          Log.d("TIS","handle task1");
                          break;
                      case 2:
                          Log.d("TIS","handle task2");
                          break;
                  }
              }
          }
      }
    
  • Manifest.xml中注册

      <application
          ........>
          <activity .../>
    
          <service android:name=".service.TestIntentService" />
      </application>
    
  • 启动Service

      //同一服务只会开启一个WorkThread,在onHandleIntent函数里依次处理Intent请求。
      Intent i0 = new Intent(this, TestIntentService.class);
      Bundle b0 = new Bundle();
      b0.putInt("taskId",0);
      i0.putExtras(b0);
      startService(i0);
    
      Intent i1 = new Intent(this, TestIntentService.class);
      Bundle b1 = new Bundle();
      b1.putInt("taskId",1);
      i1.putExtras(b1);
      startService(i1);
    
      Intent i2 = new Intent(this, TestIntentService.class);
      Bundle b2 = new Bundle();
      b2.putInt("taskId",2);
      i2.putExtras(b2);
      startService(i2);
    
      startService(i1);
      startService(i0);
    
  • 运行结果及生命周期

      D/TIS: onCreate()
      D/TIS: onStartCommand()
      D/TIS: handle task0
      D/TIS: onStartCommand()
      D/TIS: onStartCommand()
      D/TIS: onStartCommand()
      D/TIS: handle task1
      D/TIS: onStartCommand()
      D/TIS: handle task2
      D/TIS: handle task1
      D/TIS: handle task0
      D/TIS: onDestroy()
    
  • Android Studio自动创建IntentService如下:

    代码没做,模板代码是提供静态方法,方便调用

      public class HelloIntentService extends IntentService {
          // TODO: Rename actions, choose action names that describe tasks that this
          // IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
          private static final String ACTION_FOO = "com.cyxoder.interstudy.service.action.FOO";
          private static final String ACTION_BAZ = "com.cyxoder.interstudy.service.action.BAZ";
      
          // TODO: Rename parameters
          private static final String EXTRA_PARAM1 = "com.cyxoder.interstudy.service.extra.PARAM1";
          private static final String EXTRA_PARAM2 = "com.cyxoder.interstudy.service.extra.PARAM2";
      
          public HelloIntentService() {
              super("HelloIntentService");
          }
      
          /**
           * Starts this service to perform action Foo with the given parameters. If
           * the service is already performing a task this action will be queued.
           *
           * @see IntentService
           */
          // TODO: Customize helper method
          public static void startActionFoo(Context context, String param1, String param2) {
              Intent intent = new Intent(context, HelloIntentService.class);
              intent.setAction(ACTION_FOO);
              intent.putExtra(EXTRA_PARAM1, param1);
              intent.putExtra(EXTRA_PARAM2, param2);
              context.startService(intent);
          }
      
          /**
           * Starts this service to perform action Baz with the given parameters. If
           * the service is already performing a task this action will be queued.
           *
           * @see IntentService
           */
          // TODO: Customize helper method
          public static void startActionBaz(Context context, String param1, String param2) {
              Intent intent = new Intent(context, HelloIntentService.class);
              intent.setAction(ACTION_BAZ);
              intent.putExtra(EXTRA_PARAM1, param1);
              intent.putExtra(EXTRA_PARAM2, param2);
              context.startService(intent);
          }
      
          @Override
          protected void onHandleIntent(Intent intent) {
              if (intent != null) {
                  final String action = intent.getAction();
                  if (ACTION_FOO.equals(action)) {
                      final String param1 = intent.getStringExtra(EXTRA_PARAM1);
                      final String param2 = intent.getStringExtra(EXTRA_PARAM2);
                      handleActionFoo(param1, param2);
                  } else if (ACTION_BAZ.equals(action)) {
                      final String param1 = intent.getStringExtra(EXTRA_PARAM1);
                      final String param2 = intent.getStringExtra(EXTRA_PARAM2);
                      handleActionBaz(param1, param2);
                  }
              }
          }
      
          /**
           * Handle action Foo in the provided background thread with the provided
           * parameters.
           */
          private void handleActionFoo(String param1, String param2) {
              // TODO: Handle action Foo
              throw new UnsupportedOperationException("Not yet implemented");
          }
      
          /**
           * Handle action Baz in the provided background thread with the provided
           * parameters.
           */
          private void handleActionBaz(String param1, String param2) {
              // TODO: Handle action Baz
              throw new UnsupportedOperationException("Not yet implemented");
      }
    
  • 原理

    IntentService在onCreate()函数中通过HandlerThread单独开启一个线程来依次处理所有Intent请求对象所对应的任务。通过onStartCommand()传递给服务intent被依次插入到工作队列中。工作队列又把intent逐个发送给onHandleIntent()。

注意:所有请求都是在一个单独的工作线程上处理的——它们可能会在必要的时候(并不会阻塞应用程序的主循环),但每次只处理一个请求。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容

  • 先贴出官方关于IntentService的解释: IntentService is a base class fo...
    Elder阅读 542评论 0 2
  • 一、IntentService简介 IntentService是Service的子类,比普通的Service增加了...
    Ten_Minutes阅读 1,598评论 2 6
  • 本篇文章是继续上篇android图片压缩上传系列-基础篇文章的续篇。主要目的是:通过Service来执行图片压缩任...
    laogui阅读 4,416评论 5 62
  • 原文地址 创建一个后台服务: IntentService类提供一个直接的结构对于一个单独后台线程执行操作。这就允许...
    CyrusChan阅读 1,259评论 0 4
  • 春风化雨 难得的是,妈妈回来的较以往早; 难得的是,和妈妈心平气和地聊起了天; 难得的是,天气微凉,而我,...
    只一阅读 649评论 0 0