Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android IntentService #8

Open
xxm-sz opened this issue Jun 28, 2019 · 0 comments
Open

Android IntentService #8

xxm-sz opened this issue Jun 28, 2019 · 0 comments

Comments

@xxm-sz
Copy link
Owner

xxm-sz commented Jun 28, 2019

Android的四大组件中,Service排行老二,在Android中的主要作用是后台服务,进行与界面无关的操作。由于Service运行在主线程,所以进行异步操作需要在子线进行。为此Android为我们提供了IntentService
IntentService是一个抽象类,继承至Service,主要方便我们新建工作线程进行异步操作。提交任务到IntentService时,异步任务以串行方式进行处理,意味着工作线程一次只处理一个任务。而且当所有任务都完成之后,会自动停止Service,不需要我们手动停止。

IntentService 的使用

  1. 我们定义DownloadService类并继承至IntentService。来模拟网络下载的过程。
public class DownloadService extends IntentService {

    private static int count = 0;

    /**
     * 主要用于调用服务类构造器
     *
     * @param name 用于区分不同任务
     */
    public DownloadService(String name) {
        super(name);
    }

    /**
     * AndroidManifest.xml配置清单需要配置
     *
     * @param
     */
    public DownloadService() {
        super("action");
    }

    /**
    *主要重写该方法,在该方法内进行异步操作。
    **/
    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i("Download", "onHandleIntent" + count);
        count++;

        String name = intent.getStringExtra("action");

        if (name.equals("download")) {
            for (int i = 0; i < 5; i++) {

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    return;
                }

                Log.i("Download", "download:" + count);
            }
        }
    }
    //以下方法的重写,仅仅为了打印日志
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("Download", "onDestroy");

    }

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

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);

        Log.i("Download", "onStart");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("Download", "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }
}

  1. 在AndroidManifest.xml配置DownloadService
<service android:name=".DownloadService"/>
  1. 在MainActivity类中循环调用Service,启动多循环任务。
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent=new Intent(this,DownloadService.class);
        for (int i =0;i<3;i++){

            intent.putExtra("action","download");
            intent.putExtra("count",""+i);
            startService(intent);

        }
    }
  1. 运行结果

分析:
从运行结果知道,IntentService在运行多个任务情况下,只调用一次onCreate,调用多次onStartCommand,跟Service的生命周期一致。但,只有在运行完download:1之后才会去运行download:2,接着是download:3。最后所有任务结束后会自动调用onDestroy,停止服务。在这里需要注意的是,和Service并不同,Service需要我们手动停止服务。对于结果的回调,可以采用接口回调,广播,EventBus

那么,IntentService是如何在Service中实现异步操作和串行处理任务的呢?

IntentService内部实现

  1. 查看IntentService的onCreate方法
 @Override
    public void onCreate() {
        super.onCreate();
        //分析一
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

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

分析一

HandThread继承Thread,通过start方法创建工作线程,内部建立Looper来达到消息循环,通过Hanlder消息机制来达到串行的效果和处理多任务。HandThreadHandler消息机制,可以另外查看文章。

分析二

ServiceHandler继承Handler,与普通的Handler并没有区别,在其内容处理handleMessage。即调用IntentServiceonHandleIntent

  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);
        }
    }
  1. 那么,当我们在Activity中重复调用startService方法时,只会多次调用onStartCommand方法,并不会重复调用onCreate方法。我们看看onStartComamnd方法的实现。
    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

可以看得出,调用了onStart方法了。而onStart方法只是将我们的Intent包装成Message,通过Handler发送出去,并在Handler中进行处理,调用我们的onHandleIntent。进而调用我们实现onHandleIntent的代码。

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

总结

IntentService并没有什么的新的技术含量,在了解HandlerTread和Handler的消息机制下,对Handler+Thread+Service作一个封装,更适合我们后台进行异步耗时操作的场景。有效避免通过new多个Thread

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant