深入Android架构(从线程到AIDL)_26 Messager框架与IMessager接口02

2、 Android的Messenger框架

复习: 线程、信息和IBinder接口
 
  • 在Android框架里,有个IBinder接口来担任跨进程的通讯。
  • 在Android框架里,也有一个Message类,两个线程之间能互传Message对象。
  • 于是,就能设计一个Messenger类来包装IBinder接口机制,让其能跨进程地将Message对象传递到另一个进程里,给其主线程(又称UI线程)。
  • 其中,由于Message类实作(Implement)了Parcelable接口,所以Messenger类可以透过IBinder接口而将Message对象传送到另一个进程里的MessengerImpl类。
  • 然后, Messenger透过Handler而将Message对象丢入UI线程的MQ里,让UI线程来处理之。
  • 在传送Message对象之前,必须先建立MessengerImpl、 Handler和myService三者之间的关系。如下图:
  • 首先myService诞生一个Handler对象,并诞生一个Messenger对象,并让Messenger指向该Handler对象。
  • 于是, Messenger对象调用Handler的getIMessenger()函数去诞生一个MessengerImpl对象,并让Messenger对象指向MessengerImpl对象。
  • 此时, MessengerImpl对象也指向Handler对象。
  • 建构完毕后,在另一个进程里的myActivity就能透过Messenger类而将Message对象传递给MessengerImpl对象。
  • 然后, MessengerImpl继续将Message对象放入主线程(main thread)的MQ里,如下图所示:
步骤是:
 
  • myActivity调用bindService()去绑定myService,取得IBinder接口。
  • 以Messenger类包装IBinder接口。
  • myActivity透过Messenger类接口将Message信息传给远方的MessengerImpl类。
  • MessengerImpl类将信息丢入对方主线程的MQ里。
  • 主线程从MQ里取得信息,并调用myService的函数来处理信息
     

程序代码
 

// myService.java
// ……….
public class myService extends Service {
    class myHandler extends Handler {
        @Override 
        public void handleMessage(Message msg) {
            //……..
            Toast.makeText(getApplicationContext(),msg.obj.toString(),
                Toast.LENGTH_SHORT).show();
            //……..
        }
    }

    final Messenger mMessenger = new Messenger(new myHandler());

    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }
}

// myActivity.java
// ………
public class myActivity extends Activity {
    Messenger mMessenger = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main); 
        bindService(new Intent(this, MessengerService.class), mConnection,
Context.BIND_AUTO_CREATE); 
    }
    
    private ServiceConnection mConnection = new ServiceConnection() {
            public void onServiceConnected(ComponentName className, IBinder ibinder)
            {
                mMessenger = new Messenger(ibinder);
            }
    }

    public void onClick() {
        Message msg = Message.obtain(null, 0, “Hello”);
        mMessenger.send(msg);
    }
}
  • 一开始,框架会诞生myService对象,此时也执行指令:

                 final Messenger mMessenger = new Messenger(new myHandler());

  • 就诞生一个myHandler对象,并且诞生一个Messenger对象,并把myHandler对象指针存入Messenger对象里。
  • 一旦myActivity执行到指令:
      bindService(new Intent(this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE);
  • 框架会调用myService的onBind()函数,其内容为:
    public IBinder onBind(Intent intent) {
               return mMessenger.getBinder();
    }
  • 此时,调用Messenger的getBinder()函数来取的MessengerImpl的IBinder接口,并回传给Android框架。如下图:
  • 接着,框架就调用myActivity的onServiceConnected()函数:
           public void onServiceConnected(ComponentName className, IBinder ibinder) {
                    mMessenger = new Messenger(ibinder);
           }
  • 此时,就让Messenger对象指向IBinder接口了。
  • 一旦myActivity执行到指令:
          public void onClick() { 
                   Message msg = Message.obtain(null, “hello”, 0, 0);
                   mMessenger.send(msg);
          }
  • 就诞生一个Message对象,然后调用Messenger的send()函数,此send()函数则调用IBinder接口的transact()函数,将Message对象传递给MessengerImpl,再透过myHandler将Message对象放入主线程的MQ里。
     
再谈线程的角色
 
  • 在Android文件里,写道:
  • 但是,有许多人看不懂其涵意。
  • 其实,它的涵意很简单。如果你并不考虑让多个线程(thread)同时来执行你的Service,你就可以透过这个机制,将多个Client端(如myActivity1, myActivity2等)送来的Message对象存入单一线程的MessageQueue里,由该线程依序逐一地处理各Client传来的Message对象。
  • 虽然多个并行的Client端线程在调用IBinder接口时,会触发多个Binder驱动线程(Binder Thread)而进入MessengerImpl,然而它们则依序将Message丢入同一个(即主线程的)MessageQueue里。因此,对于Service而言,还是单线程的情境,你在撰写myService程序代码时,不必担心多线程之间的数据冲突问题。
     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

思忖小下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值