Service与IntentService的区别

Android中的Service是用于后台服务的,当应用程序被挂到后台的时候,为了保证应用的某些组件仍然可以工作而引入了Service这个概念,那么这里面要强调的是Service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,也就是说,在更多时候不建议在Service中编写耗时的逻辑和操作,否则会引起ANR。

那么我们当我们编写的耗时逻辑,不得不被service来管理的时候,就需要引入IntentService,IntentService是继承Service的,那么它包含了Service的全部特性,当然也包含service的生命周期,那么与service不同的是,IntentService在执行onCreate操作的时候,内部开了一个线程,去你执行你的耗时操作。

IntentService是通过Handler looper message的方式实现了一个多线程的操作,同时耗时操作也可以被这个线程管理和执行,同时不会产生ANR的情况。

-------------------------------------------------------------

Service

Service 是长期运行在后台的应用程序组件。

Service 不是一个单独的进程,它和应用程序在同一个进程中,Service 也不是一个线程,它和线程没有任何关系,所以它不能直接处理耗时操作。如果直接把耗时操作放在 Service 的 onStartCommand() 中,很容易引起 ANR .如果有耗时操作就必须开启一个单独的线程来处理。

IntentService

IntentService 是继承于 Service 并处理异步请求的一个类,在 IntentService 内有一个工作线程来处理耗时操作,启动 IntentService 的方式和启动传统 Service 一样,同时,当任务执行完后,IntentService 会自动停止,而不需要我们去手动控制。另外,可以启动 IntentService 多次,而每一个耗时操作会以工作队列的方式在IntentService 的 onHandleIntent 回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。

而且,所有请求都在一个单线程中,不会阻塞应用程序的主线程(UI Thread),同一时间只处理一个请求。 那么,用 IntentService 有什么好处呢?首先,我们省去了在 Service 中手动开线程的麻烦,第二,当操作完成时,我们不用手动停止 Service。

比较Service 和 IntentService 处理耗时操作的结果

service:

public class MyService2 extends Service {
    private static final String TAG = "MyService2";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        LogUtil.e(TAG, "onCreate");
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LogUtil.e(TAG, "onStartCommand");

        //因为service在主线程中 所以操作耗时操作必须创建子线程
        new Thread(new Runnable() {
            @Override
            public void run() {

                LogUtil.e(TAG, "onStartCommand");

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

                LogUtil.e(TAG, "睡眠结束");
            }
        });
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        LogUtil.e(TAG, "onDestroy");

    }
}

如果在onStartCommand中不开启线程直接支持耗时操作,因为时间短出现了:Skipped 60 frames!  The application may be doing too much work on its main thread. 


intentService:

public class MyIntentService2 extends IntentService {
    private static final String TAG = "MyIntentService2";

    public MyIntentService2() {
        super("MyIntentService2");    //调用父类的有参构造函数
    }
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {

        // 经测试,IntentService里面是可以进行耗时的操作的
        //IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent
        //对于异步的startService请求,IntentService会处理完成一个之后再处理第二个

        LogUtil.e(TAG, "onStart");

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LogUtil.e(TAG, "睡眠结束");

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        LogUtil.e(TAG, "onDestroy");
    }
}

servicedemoActivity

@OnClick({R.id.button, R.id.button2, R.id.button3, R.id.button4})
    public void onViewClicked(View view) {

        switch (view.getId()) {
            case R.id.button:
                //如果不开线程 会造成线程阻塞ANR
                startService(new Intent(this, MyService2.class));
                break;

            case R.id.button2:
                stopService(new Intent(this, MyService2.class));
                break;
            case R.id.button3:

                //连续两次启动IntentService,会发现应用程序不会阻塞,
                //而且最重要的是第二次的请求会再第一个请求结束之后运行
                // (这个证实了IntentService采用单独的线程每次只从队列中拿出一个请求进行处理)
                startService(new Intent(this, MyIntentService2.class));
                startService(new Intent(this, MyIntentService2.class));

                break;

            case R.id.button4:

                //不用关闭

                break;
        }
    }

打印结果:

因为是startService启动的服务,只要android系统不关闭和主动调用stopService方法,service会一直运行在后台。

如果希望启动服务的Activity关闭的时候service也跟着一起关闭,这就需要将service和Activity进行绑定。bindService

05-28 14:54:01.105 8224-8224/com.sdhmw.com.mystudy E/MyService2: onCreate
05-28 14:54:01.105 8224-8224/com.sdhmw.com.mystudy E/MyService2: onStartCommand
05-28 14:56:52.015 8224-8224/com.sdhmw.com.mystudy D/ViewRootImpl: ViewPostImeInputStage processPointer 0
05-28 14:56:52.095 8224-8224/com.sdhmw.com.mystudy D/ViewRootImpl: ViewPostImeInputStage processPointer 1
05-28 14:56:52.095 8224-8224/com.sdhmw.com.mystudy E/MyService2: onDestroy

05-28 14:57:22.205 8224-16273/com.sdhmw.com.mystudy E/MyIntentService2: onStart
05-28 14:57:23.205 8224-16273/com.sdhmw.com.mystudy E/MyIntentService2: 睡眠结束
05-28 14:57:23.205 8224-16273/com.sdhmw.com.mystudy E/MyIntentService2: onStart
05-28 14:57:24.205 8224-16273/com.sdhmw.com.mystudy E/MyIntentService2: 睡眠结束
05-28 14:57:24.205 8224-8224/com.sdhmw.com.mystudy E/MyIntentService2: onDestroy


连续两次启动IntentService,会发现应用程序不会阻塞,
而且最重要的是第二次的请求会再第一个请求结束之后运行
(这个证实了IntentService采用单独的线程每次只从队列中拿出一个请求进行处理)
IntentService不需要主动方法去关闭,自动关闭。


bindService 返回键Activity关闭的时候自动关闭:

05-28 15:21:26.295 7203-7203/com.sdhmw.com.mystudy E/MyService2: onCreate
05-28 15:21:26.295 7203-7203/com.sdhmw.com.mystudy E/MyService2: BinderStart
05-28 15:21:26.295 7203-7203/com.sdhmw.com.mystudy E/ServiceDemoActivity: onServiceConnected name:ComponentInfo{com.sdhmw.com.mystudy/com.sdhmw.com.mystudy.MyService2}
05-28 15:21:26.295 7203-7203/com.sdhmw.com.mystudy E/ServiceDemoActivity: onServiceConnected service:com.sdhmw.com.mystudy.MyService2$MyBinder@b888e6a
05-28 15:21:32.105 7203-7203/com.sdhmw.com.mystudy D/ViewRootImpl: ViewPostImeInputStage processKey 0
05-28 15:21:32.185 7203-7203/com.sdhmw.com.mystudy D/ViewRootImpl: ViewPostImeInputStage processKey 1
05-28 15:21:32.625 7203-7203/com.sdhmw.com.mystudy D/ViewRootImpl: #3 mView = null
05-28 15:21:32.635 7203-7203/com.sdhmw.com.mystudy E/MyService2: onDestroy


service里面的onstart()方法和onStartCommand()方法的区别

参考:https://blog.csdn.net/kuangren_01/article/details/9427839





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿姨不可以嘛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值