Android-IntentService详细使用及源码分析

简介

IntentService is a base class for {@link Service}s that handle asynchronous
requests (expressed as {@link Intent}s) on demand. Clients send requests
through {@link android.content.Context#startService(Intent)} calls; the
service is started as needed, handles each Intent in turn using a worker
thread, and stops itself when it runs out of work.

Intentservice是一个处理异步请求的基类,其实是个抽象类,客户端使用startservice方法发送请求,service根据需要启动后,会在工作线程里处理每次的intent,如果你想停止它,使用stopSelf方法。英语一般!

基本使用

接下来说下基本使用,基本使用不复杂,老实说是不复杂,但是还是有出错的时候。比如:构造的时候要传入名称。否则就报错。

1.创建Intentservice的子类,子类的构造,不要传入参数,使用默认构造,但是super要传入一个name,官方解释是只是作为测试用.
onHandleIntent()方法就是真正的处理耗时任务的方法。注意我还做了是否为主线程的判断日志。

public class MyIntentService extends IntentService {

    private static final String TAG = "MyIntentService";
	
    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.d(TAG, "onHandleIntent: " + (Looper.getMainLooper() == Looper.myLooper()));
        //这里处理耗时任务,如请求网络数据
    }
}

2.注册清单文件,老实说我第一次接触intentservice,一看是异步处理,我以为不需要注册,可是后来我错了,你可以看看它的继承关系就知道了,它和service还是有关系。所以还要注册。
public class MyIntentService extends IntentService
public abstract class IntentService extends Service

 <service
            android:name=".MyIntentService"
            android:exported="false" />

3.启动Intentservice

  startService(new Intent(this, MyIntentService.class));

好了,一个简单的流程结束了。很简单。

源码分析

开头的简介里说了,它是作为一个异步任务机制存在的,所以他肯定有线程相关的对象了。比如任务线程workThread。进入Intentservice,立马就能看到创建了一个ServiceHandler.

private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
        	// 这不就是咱们处理耗时任务的方法
            onHandleIntent((Intent)msg.obj);
            // 最后还终止了自己。
            stopSelf(msg.arg1);
        }
    }

intentservice总归还是一个service,既然是service,咱们就要看生命周期方法。比如onCreate onStartCommand.

 @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();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    /**
     * You should not override this method for your IntentService. Instead,
     * override {@link #onHandleIntent}, which the system calls when the IntentService
     * receives a start request.
     * @see android.app.Service#onStartCommand
     */
    @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 onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

onCreate:里面创建了一个HandlerThread,它是谁,它是thread,你可以理解为它是为了为你准备好Looper对象的线程。如果这块不理解,你可以自行查阅。大家都知道,UI线程默认已经创建了Looper对象的,但是现在创建了一个子线程,要发送handler的消息,也要有looper对象,但是handlerThread已经帮你创建好了,你就可以直接使用了。
onStartCommand方法里调用了onstart方法,这个方法发送了消息。谁发的,serviceHandler,这不就又回到了servicehandler的创建。handleMessage里,处理完耗时任务后,就停止了自身。

   @Override
   public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
发布了69 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chentaishan/article/details/104344454