IntentService原理

2018-03-05  本文已影响0人  帝王鲨kingcp

IntentService是一个特殊的Service,它继承Service并且它是一个抽象类,因此必须创建它的子类才能使用。IntentService因为是一个Service,所以适用优先级要求高的后台线程,线程结束,IntentService就结束了。

在IntentService被初始化时候,会创建一个HandlerThread和ServiceHandler,用于实现整个流程。

 @Override
    public void onCreate() {
        // TODO: It would be nice to have an option to hold a partial wakelock
        // during processing, and to have a static startService(Context, Intent)
        // method that would launch the service & hand off a wakelock.

        super.onCreate();
    // 1. 通过实例化HandlerThread新建线程 & 启动;故 使用IntentService时,不需额外新建线程
    // HandlerThread继承自Thread,内部封装了 Looper
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();
    // 2. 获得工作线程的 Looper & 维护自己的工作队列
        mServiceLooper = thread.getLooper();
   // 3. 新建mServiceHandler & 绑定上述获得Looper
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

HandlerThread

HandlerThread继承Thread,是一个可以使用Handler的Thread。run方法中通过Looper.prepare,Looper.loop形成消息循环队里。HandlerThread与普通Thread的区别在于HandlerThread需要通过handler来交待一个具体的任务。HandlerThread就用在IntentService,在后台线程为其提供一个消息队列。

public class HandlerThread extends Thread {
 
    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }
    
}

在使用IntentService时,用start开启任务。start会将任务交给mServiceHandler中的handleMessage来处理。具体是处理由onHandleIntent来完成,子类会重写这个方法。然后stopSelf(int startId)来结束(会等所有消息处理完后才终止服务)。

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
    // 1. 获得ServiceHandler消息的引用
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
    // 2. 把 Intent参数 包装到 message 的 obj 发送消息中,
    //这里的Intent  = 启动服务时startService(Intent) 里传入的 Intent
        msg.obj = intent;
// 3. 发送消息,即 添加到消息队列里
        mServiceHandler.sendMessage(msg);
    }
private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }
// IntentService的handleMessage()把接收的消息交给onHandleIntent()处理
        @Override
        public void handleMessage(Message msg) {
           // onHandleIntent 方法在工作线程中执行
          // onHandleIntent() = 抽象方法,使用时需重写 
            onHandleIntent((Intent)msg.obj);
         // 执行完调用 stopSelf() 结束服务
            stopSelf(msg.arg1);
        }
    }

IntentService实例

启动3次intentService,三次任务会排队依次执行。

public class IntentService_Activity extends Activity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.intentservice_activity);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(IntentService_Activity.this,IntentService_Service.class);
                intent.putExtra("task_name","service_task1");
                startService(intent);

                intent.putExtra("task_name","service_task2");
                startService(intent);

                intent.putExtra("task_name","service_task3");
                startService(intent);
            }
        });
    }
}
public class IntentService_Service extends IntentService {

    private static final String TAG = "IntentService_Service";

    public IntentService_Service() {
        // 调用父类的构造函数
        // 参数 = 工作线程的名字
        super(TAG);
        Log.i(TAG, "IntentService_Service: 初始化");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate: ");
    }

    /** 
     * 复写onHandleIntent()方法
     * 根据 Intent实现 耗时任务 操作
     **/  
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.i(TAG, "onHandleIntent: begin task " + intent.getStringExtra("task_name"));
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy: 队列中人任务已完成");
    }
}

执行结果如下:若启动IntentService 多次,那么每个耗时操作则以队列的方式在IntentService的 onHandleIntent回调方法中依次执行,执行完自动结束


执行结果.png

执行流程

执行流程

IntentService和Service的对比

image.png

IntentService和Thread的对比

image
上一篇下一篇

猜你喜欢

热点阅读