Activity与Service的数据通信

1.Service基础

(1)service的生命周期

(2)start---->stop调用:

(3)bind--->unbind调用:

bindService(intent, serviceConnection, BIND_AUTO_CREATE);

flag:

 @param flags Operation options for the binding.  May be 0,
*          {@link #BIND_AUTO_CREATE}, {@link #BIND_DEBUG_UNBIND},
*          {@link #BIND_NOT_FOREGROUND}, {@link #BIND_ABOVE_CLIENT},
*          {@link #BIND_ALLOW_OOM_MANAGEMENT}, or
*          {@link #BIND_WAIVE_PRIORITY}.

问:当 flags 不等于 BIND_AUTO_CREATE 时,bindService还会自动启动service吗?

答:不会。

问:当 flags 不等于 BIND_AUTO_CREATE,调用bindService前service未启动。一段时间之后,service被start,此时系统还会尝试之前的bind动作吗?

答:会。
原文:https://blog.csdn.net/lxyyzm/article/details/54669334 

所以当flag为0时,如果没有startService,只bindService,是不会启动并绑定服务的。

(3)先start后bind(flag = BIND_AUTO_CREATE):

先start后bind(flag = 0)和(flag = BIND_AUTO_CREATE)一样,点击start时,调用oncreate,onstratcommand。点击bind时,调用onbind。

 

(4)先bind(flag = BIND_AUTO_CREATE)后start

点击bind:调用oncreate,onbind。所以这个标记是会自动创建服务并绑定。

点击start:调用onstartcommand。

先bind(flag = 0)后start

点击bind:什么都不打印

点击start,调用如下,service被start,此时系统还会尝试之前的bind动作。

 

(5)当start和bind都调用后,怎么关闭:

先stop再unbind(bind的flag = 0):

点击stop后:

点击unbind后:什么都没有打印。

先stop再unbind(bind的flag = BIND_AUTO_CREATE):

点击stop:没有打印

点击unbind:

(6)先unbind(bind的flag = 0)再stop:

点击unbind,调用onunbind;

点击stop,调用ondestory。

先unbind(bind的flag = BIND_AUTO_CREATE)再stop和上面情况一样。按正常顺序,onunbind,ondestory执行。

总结:从(3)和(6)可以看出,当正常的start,bind,unbind, stop时,flag的值的两种情况是一样的,方法调用也是正常的。

从(4)和(5)可以看出,都是反方向的调用两个方法,想bind之前必须start服务,要么自己start(使用flag=BIND_AUTO_CREATE),要么手动调用start方法后,才能正常开启并绑定服务。

停止时。当flag=BIND_AUTO_CREATE,调stop没用,只有unbind时才会走ondestory销毁服务。当bind的flag = 0,点击stop会先调onunbind,再调ondestory。

2.activity传递数据给service

(1)intent方式

activity中:

intent = new Intent(ServiceActivity.this, MyService.class);
        intent.putExtra("data", "ysl");

startService(intent);

bindService(intent, serviceConnection, BIND_AUTO_CREATE);

service中:

@Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind is invoke");
        String data = intent.getStringExtra("data");
        Log.d(TAG, "onBind is invoke--->"+data);
        return null;
    }

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand is invoke");
        String data = intent.getStringExtra("data");
        Log.d(TAG, "onStartCommand is invoke--->"+data);
        return super.onStartCommand(intent, flags, startId);
    }

不管是用start还是bind,都可以使用intent传递数据

(2)使用binder对象

在service中:

@Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind is invoke");
        return new MyBinder();
    }

    public class MyBinder extends Binder{
        public void setData(String data){
            Toast.makeText(MyService.this, data, Toast.LENGTH_SHORT).show();
        }
    }

activity中:

bindService(intent, serviceConnection, BIND_AUTO_CREATE);


private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected is invoke");
            MyBinder myBinder = (MyBinder) service;
            myBinder.setData("bindService启动服务了");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected is invoke");
        }
    };

在serviceConnection接口中,第二个参数Ibinder,就是我们在service中的onBind方法返回的对象MyBinder。这种方式只适用于bindservice使用。

(3)接口回调

activity给service传递数据:

接口设置在activity中:

private OnActivityDataChangedListener onActivityDataChangedListener;

    public interface OnActivityDataChangedListener {
        void onActivityDataChanged(String string);
    }

    public void setOnActivityDataChangedListener(OnActivityDataChangedListener onActivityDataChangedListener) {
        this.onActivityDataChangedListener = onActivityDataChangedListener;
    }

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected is invoke");
            myBinder.setActivity(ServiceActivity.this);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected is invoke");
        }
    };

//任意控件点击事件,触发数据变化
findViewById(R.id.startService).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onActivityDataChangedListener != null) {
                    onActivityDataChangedListener.onActivityDataChanged("哈哈哈,activity的数据变了。activity");
                } else {
                    throw new IllegalArgumentException("activity must invoke setOnActivityDataChangedListener()");
                }
            }
        });

service中:

@Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind is invoke");
          return new MyBinder();
    }

    public class MyBinder extends Binder{
        public void setActivity(Activity activity){
            ((ServiceActivity)activity).setOnActivityDataChangedListener(new ServiceActivity.OnActivityDataChangedListener() {
                @Override
                public void onActivityDataChanged(String string) {
                    Log.d(TAG, "onActivityDataChanged is invoke  "+string);
                }
            });
        }
    }

mybinder中有个setactivity()方法,当连接建立后,把activity设置进去。然后实现activity的接口。当activity调用数据变化接口方法时,service中的实现方法就会自动触发,获取到数据变化。

service数据变化也可以通知到activity中,同理使用接口方式:

接口在service中:

public interface CallBack{
        void dataCallBack(String data);
    }
    public void setDataCallBack(CallBack callBack){
        this.callback = callBack;
    }
    private CallBack callback;

@Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind is invoke");
          return new MyBinder();
    }

    public class MyBinder extends Binder{
        public MyService getMyService(){
            return MyService.this;
        }
        }
    }

//这段就是触发接口的代码,可以在获取到数据或数据有变化时,来调用触发。
if (callback != null) {
            callback.dataCallBack("哈哈哈,service的数据变了。service");
        } else {
            throw new IllegalArgumentException("activity must invoke setOnActivityDataChangedListener()");
        }

activity中实现:

private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected is invoke");
            MyBinder myBinder = (MyBinder) service;
            myBinder.getMyService().setDataCallBack(new CallBack() {
                @Override
                public void dataCallBack(String data) {
                    Log.d(TAG, "setDataCallBack is invoke   "+data);
                }
            });
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected is invoke");
        }
    };

可以发现,接口回调方法可以在任意两个类中传递数据。前提是:获取方要能够拿到被获取方的对象,并调用被获取方的接口,实现接口中的方法即可。而被获取可以在获取方注册后,随时随地触发接口并传递数据出去。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值