日报2015/10/16(极客学院安卓视频学习)

启动 Service 并传递数据(通过Intent)

启动的时候

Intent i= new Intent(MainActivity.this, MyService.class);
i.putExtra("data",editText.getText().toString());
startService(i);

在MyService里面,因为之前是startService,与之对应的是onStartCommand,所以在这里面接受数据就好啦

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        data = intent.getStringExtra("data");

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

启动一次服务,输入文本,再次点击启动按钮

10-16 22:07:03.825  10312-10312/com.jackie.courseservice V/jackie﹕ 开始服务
10-16 22:07:03.830  10312-10312/com.jackie.courseservice V/jackie﹕ Service created
10-16 22:07:03.830  10312-10312/com.jackie.courseservice V/jackie﹕ Command started
10-16 22:07:03.835  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...默认信息
10-16 22:07:05.835  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...
10-16 22:07:07.835  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...
10-16 22:07:09.835  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...
10-16 22:07:11.835  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...
10-16 22:07:13.835  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...
10-16 22:07:15.835  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...
10-16 22:07:17.840  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...
10-16 22:07:19.835  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...
10-16 22:07:20.630  10312-10312/com.jackie.courseservice V/jackie﹕ 开始服务
10-16 22:07:21.835  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...修改后再次启动
10-16 22:07:23.840  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...修改后再次启动
10-16 22:07:25.840  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...修改后再次启动
10-16 22:07:27.840  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...修改后再次启动
10-16 22:07:29.840  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...修改后再次启动
10-16 22:07:31.840  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...修改后再次启动
10-16 22:07:33.840  10312-10746/com.jackie.courseservice V/jackie﹕ 服务正在运行...修改后再次启动
10-16 22:07:33.920  10312-10312/com.jackie.courseservice V/jackie﹕ 停止服务
10-16 22:07:33.925  10312-10312/com.jackie.courseservice V/jackie﹕ Service destroyed

这里写图片描述

绑定 Service 进行通信(上)

除了使用Intent进行通信,也可以通过Service中的Binder来通信,这里就需要将Activity和Service绑定(bind)在一起了

1、绑定服务

bindService(new Intent(MainActivity.this, MyService.class), this, BIND_AUTO_CREATE);

2、Service中设置一个成员变量data,来呈现两边数据的同步,并且,在Service创建后启动一个线程,不停地打印这个data,观察它的变化

    public String data = "默认信息";
    ...
                while (isRunning){
                    Log.v("jackie","服务正在运行..."+data);
                    try {
                        sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

3、关键:在Service里面自己写一个MyBinder,继承Binder,里面写一个方法,用来设置成员变量data的值,并且,在onBind(Intent intent)方法里面返回这个自己定义的MyBinder

    @Override
    public IBinder onBind(Intent intent) {
        return new MyBinder();

    }

这个返回的自定义Binder就是Service和Activity沟通的桥梁

4、由于在为MainActivity绑定Service的时候,是将MainActivity作为一个ServiceConnection传参,所以在这个必须重写的方法里,IBinder service 其实就是之前返回的MyBinder

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //这里的binder用于接受onBinder返回的MyBinder
        binder = (MyService.MyBinder) service;
    }

5、通过这个binder,来在按钮点击事件里改变Service中data的值

binder.setData(editText.getText().toString());

这样就实现了在Activity里面改变Service中的成员变量,关键就在于这个binder

10-16 21:57:25.795   27876-5582/com.jackie.courseservice V/jackie﹕ 服务正在运行...默认信息
10-16 21:57:27.795   27876-5582/com.jackie.courseservice V/jackie﹕ 服务正在运行...默认信息
10-16 21:57:29.800   27876-5582/com.jackie.courseservice V/jackie﹕ 服务正在运行...默认信息
10-16 21:57:31.795   27876-5582/com.jackie.courseservice V/jackie﹕ 服务正在运行...默认信息
10-16 21:57:31.960  27876-27876/com.jackie.courseservice W/IInputConnectionWrapper﹕ showStatusIcon on inactive InputConnection
10-16 21:57:33.800   27876-5582/com.jackie.courseservice V/jackie﹕ 服务正在运行...默认信息
10-16 21:57:35.540  27876-27876/com.jackie.courseservice V/jackie﹕ 同步数据
10-16 21:57:35.795   27876-5582/com.jackie.courseservice V/jackie﹕ 服务正在运行...我是绑定后修改的值
10-16 21:57:37.795   27876-5582/com.jackie.courseservice V/jackie﹕ 服务正在运行...我是绑定后修改的值
10-16 21:57:39.795   27876-5582/com.jackie.courseservice V/jackie﹕ 服务正在运行...我是绑定后修改的值
10-16 21:57:41.800   27876-5582/com.jackie.courseservice V/jackie﹕ 服务正在运行...我是绑定后修改的值

这里写图片描述


绑定 Service 进行通信(下)

上面我们通过binder对Service里面的数据进行了访问操作,并且在LogCat里面打印了这个数据,那么如果不想看Log,直接把数据呈现在用户可以交互到的Activity岂不是更加方便吗,所以,这里可以尝试一下,如何侦听被绑定的 Service 的内部状态。

还是之前的打印线程,给一个count,每次加一

...
count++;
Log.v("jackie","服务正在运行..."+count);
...

在Activity里面弄一个显示区域显示这个count

这个实现的关键就是:回调机制 Callback,Service里面那个自己定义的MyBinder里面写一个获取当前Service的方法

        public MyService getService() {
            return MyService.this;
        }

然后定义一个接口Callback,并且该Service要有一个Callback类型的成员变量

    private Callback callback;

    public static interface Callback {
        public void onDataChange(String data);
    }

然后线程打印的时候,循环里面有一句

count++;
if (callback != null) {
    callback.onDataChange("服务正在运行..." + count);
}

在Activity中通过获取Callback并重写onDataChange方法就可以监听线程里面count的值了

由于其他线程是不可以改变UI线程的内容的,所以我们需要Handler来通知主线程改变TextView的内容

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        binder = (MyService.MyBinder) service;
        binder.getService().setCallback(new MyService.Callback() {
            @Override
            public void onDataChange(String data) {
                Message msg = new Message();
                Bundle b = new Bundle();
                b.putString("data", data);
                msg.setData(b);
                handler.sendMessage(msg);
            }
        });
//        Log.v("jackie", "Service Connected");

    }
        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                tvShow.setText(msg.getData().getString("data"));
            }
        };

这里写图片描述
这里写图片描述

po主要说一句,Callback太特么好用了!Activity可以为自己给绑定的Service的Callback重写自己需要的功能,然后MyService启动之后它的Callback执行的就是重写过的功能了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值