activity和service相互传递信息

activity和service相互传递信息

在业务中经常会在service中执行后台操作,一般情况下都会跟activity进行绑定,这样activity就能控制service了,但是在业务中,activity和service的信息交流是要互通的。解决方案有多种,这里说明的是采用接口的方案达到互通消息的目的。

首先activity通过binder来绑定service,然后在绑定binder中传递service实例,从而在activity中获取service实例,再绑定接口。比如我在service中不断的请求网络接口,需要将返回值告诉activity,而activity需要能够开启或者暂停这个网络请求。下面上简单的业务代码。

1.创建service,在里面创建一个公共的类,继承Binder,这个类的对象是activity绑定service之后可以获取到的。2.在该类中编写一个方法,返回值就是该service的类型,这样activity就能获取到service的实例对象。                  3.最后在service中编写接口,用于在activity中监听,如果service中有需要像activity返回的值就进行返回。


Service代码:在work方法中返回MyService对象,在workThreak中有数据需要向activity传递。

startWork和stopWork方法是activity用来开始和停止线程中工作的停止和开始。

public class MyService extends Service {

    private Work work;
    //有可能会内存泄漏,采用虚引用
    private WeakReference<MyService> myService = new WeakReference<>(MyService.this);
    private static final String TAG = "MyService";

    public MyService() {
        threadFlag = true;
        workThread.start();
    }

    private Work getWork() {
        if (work == null) {
            work = new Work();
        }
        return work;
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind");
        return getWork();
    }

    @Override
    public void onDestroy() {
        threadFlag = false;
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }

    public class Work extends Binder {
        public void startWork() {
            //开始工作
            flag = true;
        }

        public void stopWork() {
            //停止工作
            flag = false;
        }

        public MyService getMyService() {
            return myService.get();
        }
    }

    //工作标识符
    private boolean flag = true;

    //线程工作标识符
    private boolean threadFlag = true;

    private int i = 0;

    //模拟后台持续工作
    private Thread workThread = new Thread() {
        @Override
        public void run() {
            while (threadFlag) {
                if (flag) {
                    //模拟子线程后台工作 然后用handler发送给主线程
                    i++;
                    SystemClock.sleep(2000);
                    Message message = handler.obtainMessage();
                    message.obj = i;
                    message.what = 1;
                    handler.sendMessage(message);
                }
            }
        }
    };
    private Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    int message = (int) msg.obj;
                    //将信息反馈给接口
                    if (callBacks != null && callBacks.size() > 0) {
                        for (CallBack callBack :
                                callBacks) {
                            callBack.postMessage(message);
                        }
                    }
            }
            super.handleMessage(msg);
        }
    };

    /**
     * 提供给activity的接口 因为存在一个服务绑定多个activity的情况 所以监听接口采用list装起来
     */

    public interface CallBack {
        void postMessage(int message);
    }

    private List<CallBack> callBacks = new LinkedList<>();

    //注册接口
    public void registerCallBack(CallBack callBack) {
        if (callBacks != null) {
            callBacks.add(callBack);
        }
    }

    /**
     * 注销接口 false注销失败
     *
     * @param callBack
     * @return
     */
    public boolean unRegisterCallBack(CallBack callBack) {
        if (callBacks != null && callBacks.contains(callBack)) {
            return callBacks.remove(callBack);
        }
        return false;
    }
}

activity代码:在serviceConnection中获取Myservice中的Work类,这样就能调用getMyservice来获取当前绑定的Service的实例,然后注册监听,就能实现service中执行的结果回显到activity中。

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private boolean bindService;
    private MyService.Work work;
    private MyService myService;
    private TextView tv_text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.btn_start).setOnClickListener(this);
        findViewById(R.id.btn_stop).setOnClickListener(this);
        tv_text = findViewById(R.id.tv_text);
        bindService();
    }

    //绑定service
    private void bindService() {
        Intent intent = new Intent(this, MyService.class);
        startService(intent);
        bindService = bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    private ServiceConnection serviceConnection = new ServiceConnection() {


        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            //获取绑定binder 强制转化为MyService.Work
            work = (MyService.Work) iBinder;
            myService = work.getMyService();
            myService.registerCallBack(callBack);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            if (myService != null) {
                myService.unRegisterCallBack(callBack);
            }
        }
    };

    private MyService.CallBack callBack = new MyService.CallBack() {
        @Override
        public void postMessage(int message) {
            tv_text.setText("service do result-----> " + message);
        }
    };

    public void unBindService() {
        if (bindService && serviceConnection != null) {
            unbindService(serviceConnection);
        }
    }

    @Override
    protected void onDestroy() {
        unBindService();
        super.onDestroy();
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_start:
                if (work!=null){
                    work.startWork();
                }
                break;
            case R.id.btn_stop:
                if (work!=null){
                    work.stopWork();
                }
                break;
        }
    }
}

github地址:点击打开链接

运行的gif图:点击打开链接

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值