Android Service服务

Android Service服务

参考:service初涉
service服务的生命周期示意图:
在这里插入图片描述

启动service的方法

1)StartService()启动Service
2)BindService()启动Service
PS:还有一种,就是启动Service后,绑定Service!

service的相关方法

onCreate():当Service第一次被创建后立即回调该方法,该方法在整个生命周期 中只会调用一次!
onDestory():当Service被关闭时会回调该方法,该方法只会回调一次!
onStartCommand(intent,flag,startId):早期版本是onStart(intent,startId), 当客户端调用startService(Intent)方法时会回调,可多次调用StartService方法, 但不会再创建新的Service对象,而是继续复用前面产生的Service对象,但会继续回调 onStartCommand()方法!
IBinder onOnbind(intent):该方法是Service都必须实现的方法,该方法会返回一个 IBinder对象,app通过该对象与Service组件进行通信!
onUnbind(intent):当该Service上绑定的所有客户端都断开时会回调该方法!

StartService启动Service

①首次启动会创建一个Service实例,依次调用onCreate()和onStartCommand()方法,此时Service 进入运行状态,如果再次调用StartService启动Service,将不会再创建新的Service对象, 系统会直接复用前面创建的Service对象,调用它的onStartCommand()方法!
②但这样的Service与它的调用者无必然的联系,就是说当调用者结束了自己的生命周期, 但是只要不调用stopService,那么Service还是会继续运行的!
③无论启动了多少次Service,只需调用一次StopService即可停掉Service

BindService启动Service

①当首次使用bindService绑定一个Service时,系统会实例化一个Service实例,并调用其onCreate()和onBind()方法,然后调用者就可以通过IBinder和Service进行交互了,此后如果再次使用bindService绑定Service,系统不会创建新的Sevice实例,也不会再调用onBind()方法,只会直接把IBinder对象传递给其他后来增加的客户端!
②如果我们解除与服务的绑定,只需调用unbindService(),此时onUnbind和onDestory方法将会被调用!这是一个客户端的情况,假如是多个客户端绑定同一个Service的话,情况如下 当一个客户完成和service之间的互动后,它调用 unbindService() 方法来解除绑定。当所有的客户端都和service解除绑定后,系统会销毁service。(除非service也被startService()方法开启)
③另外,和上面那张情况不同,bindService模式下的Service是与调用者相互关联的,可以理解为 “一条绳子上的蚂蚱”,要死一起死,在bindService后,一旦调用者销毁,那么Service也立即终止!
通过BindService调用Service时调用的Context的bindService的解析 bindService(Intent Service,ServiceConnection conn,int flags)
service:通过该intent指定要启动的Service
conn:ServiceConnection对象,用户监听访问者与Service间的连接情况, 连接成功回调该对象中的**onServiceConnected(ComponentName,IBinder)**方法; 如果Service所在的宿主由于异常终止或者其他原因终止,导致Service与访问者间断开 连接时调用onServiceDisconnected(CompanentName)方法,主动通过unBindService() 方法断开并不会调用上述方法!
flags:指定绑定时是否自动创建Service(如果Service还未创建), 参数可以是0(不自动创建),BIND_AUTO_CREATE(自动创建)

StartService启动Service后bindService绑定

如果Service已经由某个客户端通过StartService()启动,接下来由其他客户端 再调用bindService()绑定到该Service后调用unbindService()解除绑定最后在 调用bindService()绑定到Service的话,此时所触发的生命周期方法如下:
onCreate( )->onStartCommand( )->onBind( )->onUnbind( )->onRebind( )
PS:前提是:onUnbind()方法返回true!!! 这里或许部分读者有疑惑了,调用了unbindService后Service不是应该调用 onDistory()方法么!其实这是因为这个Service是由我们的StartService来启动的 ,所以你调用onUnbind()方法取消绑定,Service也是不会终止的!
得出的结论: 假如我们使用bindService来绑定一个启动的Service,注意是已经启动的Service!!! 系统只是将Service的内部IBinder对象传递给Activity,并不会将Service的生命周期 与Activity绑定,因此调用unBindService( )方法取消绑定时,Service也不会被销毁!

总结:就是通过StartService启动的,停止时用stopService;用bindService启动的service,停止时用unBindService。不然的话,是无法停止service的。

public class TestService extends Service {
    private final static String TAG = "TestService";
    private int count;
    private boolean quit;

    //定义onBinder方法所返回的对象
    private MyBinder binder = new MyBinder();
    public class MyBinder extends Binder
    {
        public int getCount()
        {
            return count;
        }
    }

    public TestService() {
        super();
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG,"onCreate");
        //创建一个线程动态地修改count的值
        new Thread()
        {
            public void run()
            {
                while(!quit)
                {
                    try
                    {
                        Thread.sleep(1000);
                    }catch(InterruptedException e){e.printStackTrace();}
                    count++;
                }
            };
        }.start();
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG,"onBind");

        return binder;
    }



    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG,"onStartCommand");

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e(TAG,"onUnbind");

        return super.onUnbind(intent);
    }

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

        super.onDestroy();
    }
    @Override
    public void onRebind(Intent intent) {
        Log.e(TAG, "onRebind");
        super.onRebind(intent);
    }
}
startService生命周期的调用顺序
startService(new Intent(SecondActivity.this,TestService.class));
stopService(new Intent(SecondActivity.this,TestService.class));

第一次点击启动service,走了onCreate和onStartCommand,第二、三次点击启动service方法,只执行了onStartCommand。点击停止service,执行了onDestroy。再点击启动service时,重新走onCreate和onStartCommand。
在这里插入图片描述

bindService的生命周期调用顺序
//保持所启动的Service的IBinder对象,同时定义一个ServiceConnection对象
    private TestService.MyBinder binder;
    private ServiceConnection conn = new ServiceConnection() {

        //Activity与Service断开连接时回调该方法
        @Override
        public void onServiceDisconnected(ComponentName name) {
            System.out.println("------Service DisConnected-------");
        }

        //Activity与Service连接成功时回调该方法
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            System.out.println("------Service Connected-------");
            binder = (TestService.MyBinder) service;
        }
    };
//bind服务
bindService(new Intent(SecondActivity.this,TestService.class),conn, Service.BIND_AUTO_CREATE);
//停止服务
Toast.makeText(getApplicationContext(), "Service的count的值为:"+ binder.getCount(), Toast.LENGTH_SHORT).show();
unbindService(conn);

第一次点击bindService时,走了onCreate和onBind,这个时候再点击bindService是不起任何作用的。点击unbindService时,走了onUnbind和onDestroy。
在这里插入图片描述

使用BindService绑定Service,依次调用onCreate(),onBind()方法,
我们可以在onBind()方法中返回自定义的IBinder对象;再接着调用的是
ServiceConnection的onServiceConnected()方法该方法中可以获得
IBinder对象,从而进行相关操作;当Service解除绑定后会自动调用
onUnbind和onDestroyed方法,当然绑定多客户端情况需要解除所有 的绑定才会调用onDestoryed方法进行销毁哦!

Service与IntentService

Service中,不能执行耗时的操作,会引起ANR异常(Application Not Responding)
IntentService中,可以执行耗时的操作。 IntentService是继承与Service并处理异步请求的一个类,在IntentService中有 一个工作线程来处理耗时操作,请求的Intent记录会加入队列。

工作流程:

客户端通过startService(Intent)来启动IntentService;
我们并不需要手动地区控制IntentService,当任务执行完后,IntentService会自动停止;
可以启动IntentService多次,每个耗时操作会以工作队列的方式在IntentService的
onHandleIntent回调方法中执行,并且每次只会执行一个工作线程,执行完一,再到二这样!

IntentService的生命周期调用

创建TestService3 服务,继承与IntentService

public class TestService3 extends IntentService {
    private final String TAG = "hehe";
    //必须实现父类的构造方法
    public TestService3()
    {
        super("TestService3");
    }

    //必须重写的核心方法
    @Override
    protected void onHandleIntent(Intent intent) {
        //Intent是从Activity发过来的,携带识别参数,根据参数不同执行不同的任务
        String action = intent.getExtras().getString("param");
        if(action.equals("s1")){
            Log.e(TAG,"启动service1");
        } else if(action.equals("s2")){
            Log.e(TAG,"启动service2");
        } else if(action.equals("s3")){
            Log.e(TAG,"启动service3");
        }

        //让服务休眠2秒
        try{
            Thread.sleep(2000);
        }catch(InterruptedException e){e.printStackTrace();}
    }

    //重写其他方法,用于查看方法的调用顺序
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG,"onBind");
        return super.onBind(intent);
    }

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

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


    @Override
    public void setIntentRedelivery(boolean enabled) {
        super.setIntentRedelivery(enabled);
        Log.e(TAG,"setIntentRedelivery");
    }

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

}

启动服务:

Intent it1 = new Intent(SecondActivity.this,TestService3.class);
                Bundle b1 = new Bundle();
                b1.putString("param", "s1");
                it1.putExtras(b1);

                Intent it2 = new Intent(SecondActivity.this,TestService3.class);
                Bundle b2 = new Bundle();
                b2.putString("param", "s2");
                it2.putExtras(b2);

                Intent it3 = new Intent(SecondActivity.this,TestService3.class);
                Bundle b3 = new Bundle();
                b3.putString("param", "s3");
                it3.putExtras(b3);

                startService(it1);
                startService(it2);
                startService(it3);

启动服务后
在这里插入图片描述
小结:

当一个后台的任务,需要分成几个子任务,然后按先后顺序执行,子任务 (简单的说就是异步操作),此时如果我们还是定义一个普通Service然后
在onStart方法中开辟线程,然后又要去控制线程,这样显得非常的繁琐;
此时应该自定义一个IntentService然后再onHandleIntent()方法中完成相关任务!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值