Service的简单使用

Service 的使用
startService 的使用
bindService的使用
IntentService
通过binder介质调用Service中的方法
下面是按钮,点击之后会用不同的方式绑定Service
这里写图片描述

1.startService—用Intent实现Activity向Service的传值
①先创建一个自定义Service继承Service 实现onBind方法,但是在startService中用不到这个方法所以先返回null

public class MyService1 extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {//创建Service,多次start的时候,也只会创建一次
        super.onCreate();
        //Thread.currentThread()得到当前的线程
       // 得到线程的名字(如果名字里面有main说明是在主线程),得到ID

 Log.e("TAG","onCreate"+Thread.currentThread().getName()+"id:"+Thread.currentThread().getId());
    }
    //连接服务后想要进行什么操作一般写在这里
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("TAG","onStartCommand");
        //intent是从Activiy里面传过来的intent,所以可以传值
        Log.e("TAG",intent.getStringExtra("name"))  ;
        //通常有三中返回值:START_STICKY(服务被异常终止时重新启动服务,没有stop服务)
        //START_NOT_STICKY(服务被异常终止时,不重新启动服务)
        //START_REDELIVER_INTENT(服务被异常终止时,重新传递intent)
        return START_REDELIVER_INTENT ;


    }

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

②在Mainfist中注册这个Service(只能这样注册)

<service android:name="com.xbl.service.MyService1"/>

③在Activty绑定这个后台服务,两个按钮,一个绑定服务,一个取消服务

case R.id.start_service_btn:// 打印出onCreat  onBind onStartCommand
                //即使关闭程序把后台清掉会依旧调用onCreat方法,说明Service会在后台中运行不会被杀死
                Intent intent1=new Intent(MainActivity.this, MyService1.class);
                //向服务传值
                intent1.putExtra("name","张三丰");
                startService(intent1);
                break;
            case R.id.stop_service_btn://onDestroy
                //只有stop了Service才会被杀死,即使退出了程序服务也会自己创建出来
                Intent intent2=new Intent(MainActivity.this, MyService1.class);
                stopService(intent2);
                break;

这个是startService的使用方法可以进行Activity向Service的传值,做一些简单的操作,无法向Activity传值,所以只能做一些简单的操作,在Service中是不能做耗时操作的,需要开启一个子线程在Service中

2.bindService–实现Service和Activty的相互通信
这个可以实现Service和Activity的互相通信,Activity可以调用Service的方法,也可以向Activity传值
①先创建一个自定义的Service继承Service,实现onBind方法,在这里onBind不能反回一个null了

public class MyBinder extends Binder{
       //这是BInder自己定义的方法
        public  void println(){
            Log.e("TAG2","我是Binder类里面的println方法");
        }
        //Actiity是不可以直接操作Service里面的对象的,所以通过Binder在这里得到MyService2对象
        public MyService2 getService(){
            return MyService2.this;
        }

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e("TAG2","onBind")  ;
        //将这个自定义的Binder对象返回
        return new MyBinder();
    }
    //有绑定就要有解除绑定
    @Override
    public boolean onUnbind(Intent intent) {
        Log.e("TAG2","onUnbind");
        return super.onUnbind(intent);
    }
    //创建

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("TAG2","onCreate");
    }
    //startService时会调用的方法,bindService的时候不会调用到这个方法

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

    }
    //销毁一个Service,他和解除绑定是两回事,一般解除绑定就会销毁服务了

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


//在Service中自定义一个方法,实现从Activity中直接调用这个方法
    public void serviceName(){
        Log.e("TAG2","我是MyService2,这是我的方法");
    }

②同样这也需要在Mainfast中进行注册

 <service android:name="com.xbl.service.MyService2"/>

有的注册的时候是需要加完整的包名和类名的,但是AS比较智能,可以直接联想出来这些东西

③在绑定服务和服务进行通信之前要现在Activity得到这个服务(Binder)的对象,得到从自定义Service中回调的Binder,需要实现一个接口

 //实现一个接口,要实现接口所实现的方法
    private ServiceConnection connection=new ServiceConnection() {
    //绑定了服务
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e("TAG2","onServiceConnected");
            //将Service里面的Bind回调过来,将binder实例化
            myBinder= (MyService2.MyBinder) service;
        }
        //这个方法很少会被调用到,没有绑定服务
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e("TAG2","onServiceDisconnected");

        }
    };

④得到这个可操作的Binder之后就可以对Binder进行操作了

//绑定Binder
case R.id.bind_service://打印:onCreat  onBind onServiceConnected  绑定两次三个方法只会执行一次
                Intent intent3 =new Intent(MainActivity.this,MyService2.class);
                //BIND_AUTO_CREATE如果没创建过BIND会自动创建
                bindService(intent3,connection,BIND_AUTO_CREATE);
                break;
            case R.id.unbind_service://onUnbind  onDestroy
                unbindService(connection);
                break;
                //调用Binder中println()方法
            case R.id.println_bind_service://打印那句话
                myBinder.println();
                break;

这样最后可以打印出那句话还有各种Service的声明周期函数
真正的实现Service和Acitivity之间的通信

应用;像我们平常的音乐播放器的播放音乐,暂停音乐的方法就可以在Service的Binder中写,直接在Activity中调用binder.play()方法什么的就可以了

3.IntentService:用队列的方式存储,排队处理,先来的先处理,等这个处理完再去处理其他的线程

①写一个自定义的IntentService类继承于IntentService,因为在Service中是无法写耗时操作的,必须要在里面写一个子线程,IntentService实现onHandleIntent方法,这个方法会启动一个子线程

public class IntentServiceDemo extends IntentService {
    int count=0;
    //重写构造方法,改成无参的
    public IntentServiceDemo() {
        super("");
    }
    //里面包含一个子线程,不用再写子线程了
    @Override
    protected void onHandleIntent(Intent intent) {
        for(int i=1;i<=5;i++){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.e("TAG3","i:"+i);
           count++;
        }
        Log.e("TAG3","count:"+count);
    }

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

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


}

②在Activity中调用此方法

case R.id.intent_service:
                Intent intentService =new Intent(MainActivity.this, IntentServiceDemo.class);
                //用startService去启动服务
                startService(intentService);
                break;

IntentService是用startService去调用的
因为是用队列的方式处理任务,所以先点击一次让i的值到3,在点击一次按钮start一次,这个时候IntentService会将上一次没有执行完的任务执行完,从4开始打印到5,然后再添加这次新的任务,从1开始打印

4.在Acticity中通过binder中介得到Service中的方法
Activity和Service一样,没办法去new 一个对象去调用方法,自己的方法只能自己使用,但是我们可以通过binder内部类获取Service里面的方法或者Service这个类,通过向Activity通信实现在Activity里面调用Service的方法
①在Service类里面写一个方法(打印输出)

 //在Service中自定义一个方法,实现从Activity中直接调用这个方法
    public void serviceName(){
        Log.e("TAG2","我是MyService2,这是我的方法");
    }

②在Service中的binder内部类中去实例化得到这个Service类,并且 return出来这个类

//里面的方法Activity可以调用
    public class MyBinder extends Binder{
        public  void println(){
            Log.e("TAG2","我是Binder类里面的println方法");
        }
        //Actiity是不可以直接操作Service里面的对象的,所以通过Binder在这里得到MyService2对象
        public MyService2 getService(){
            return MyService2.this;
        }

    }

③在Activiy中得到这个Service类(通过回调的方式,并没有实例化)

case R.id.get_service:
                //在通过binder得到这个Service类之前一定要先绑定Binder
                MyService2 myService2=myBinder.getService();
                myService2.serviceName();
                break;

这样就可以通过myBinder.getService();得到Service的实体类,也可以调用它的方法了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值