如何使用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()。

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值