Android Service的Binder通信机制

39 篇文章 0 订阅

Service 的启动方式

  • 使用startService()启动,此时无法实现与启动者的通信,当启动对象结束时,Service仍然会在后台运行,使用stopService()可以停止Service的运行.
  • 使用bindService()将启动Service的对象进行绑定,使用unBindService()停止绑定,并且结束运行。现在介绍此方式。

Binder对象

Binder对象相当于Service对象的钩子,其他对象绑定Service时,Service会将该Binder对象返回给绑定者,使之能够通信.
Binder是Android进程间通信的一种方式。
我们自定义的Service类中,必须继承Binder类,在此类中,暴露我们要通信的数据

这个Service用于在后台更新一个Count变量,Binder将提供这个Count对象的接口,用于通信

public class MyService extends Service {

    // 使用一个变量更新数据,显示Binder的效果
    private int count = 0;
    private boolean quit = false;

    // Binder对象相当于Service对象的钩子,其他对象绑定Service时
    // Service会将该Binder对象返回给绑定者,使之能够通信
    public class MyBinder extends Binder {
        public int getCount() {
            return count;
        }
    }

    private MyBinder binder = new MyBinder();

    @Override
    public IBinder onBind(Intent arg0) {
        Log.v("LOG", "Service -- OnBind()");
        return binder;
    }

    // 启动一个新线程更新数据
    @Override
    public void onCreate() {
        super.onCreate();
        Log.v("LOG", "Service -- OnCreate()");
        new Thread() {
            public void run() {
                while (!quit) {
                    count++;
                    Log.w("LOG", count+" -----------");
                    try {
                        sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
        }.start();
    }

    // 关闭线程
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.v("LOG", "Service -- OnDestory()");
        quit = true;
    }
}

ServiceConnection接口

Interface for monitoring the state of an application service. See Service and Context.bindService() for more information.
Like many callbacks from the system, the methods on this class are called from the main thread of your process.
API 中描述的意思是一个用于监控Service是否连接的接口,他的onServiceDisconnected()在Service onBind()后回调,用于获取Binder对象

此处使用onServiceDisconnected()获取Binder对象

// 用于接收Binder的回传值
    private ServiceConnection conn = new ServiceConnection() {

        // 与Service断开连接时回调
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.v("LOG", "ServiceConnection -- onServiceDisconnected()");
        }

        // Activity与Service绑定成功时回调
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            Log.v("LOG", "ServiceConnection -- onServiceConnected()");
            // 在回调方法中获取IBinder对象
            mBinder = (MyBinder) binder;
        }
    };

完整的Activity如下

public class MainActivity extends ActionBarActivity {

    private TextView mTvNum;
    private MyService.MyBinder mBinder;
    private boolean quit = false;
    // 用于接收Binder的回传值
    private ServiceConnection conn = new ServiceConnection() {

        // 与Service断开连接时回调
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.v("LOG", "ServiceConnection -- onServiceDisconnected()");
        }

        // Activity与Service绑定成功时回调
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            Log.v("LOG", "ServiceConnection -- onServiceConnected()");
            // 在回调方法中获取IBinder对象
            mBinder = (MyBinder) binder;
        }
    };

    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            if (msg.what == 0x10) {
                mTvNum.setText(msg.obj + "");
            }
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTvNum = (TextView) findViewById(R.id.id_tv_num);

    }

    // 绑定Service
    public void btn_bindService(View view) {
        Intent intent = new Intent(this, MyService.class);
        bindService(intent, conn, BIND_AUTO_CREATE);// 指定标志为,自动创建Service
        // 更新UI
        new Thread() {
            public void run() {
                while (!quit) {
                    try {
                        Message msg = Message.obtain();
                        msg.what = 0x10;
                        if (mBinder != null) {
                            Log.e("LOG", mBinder.getCount() + "");
                            msg.obj = mBinder.getCount();
                        }
                        mHandler.sendMessage(msg);
                        sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
        }.start();
    }

    // 取消绑定的Service
    public void btn_unBindService(View view) {
        quit = true;
        unbindService(conn);
    }

    public void btn_getBinderState(View view) {
        if (mBinder != null)
            Log.v("LOG", mBinder.getCount() + "");
        else
            Log.v("LOG", "Binder is null");
    }

}

本示例实现的效果也非常简单,Activity中更新来自Service的count值布局代码就不放了
这里写图片描述

回调顺序

05-17 07:23:36.455: V/LOG(6583): Service -- OnCreate()
05-17 07:23:36.456: V/LOG(6583): Service -- OnBind()

05-17 07:23:36.472: V/LOG(6583): ServiceConnection -- onServiceConnected()

05-17 07:23:40.334: V/LOG(6583): Service -- OnDestory()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值