美食家大橙子 发表于 2025-1-11 19:55:33

深入Android架构(从线程到AIDL)_21 IPC的Proxy-Stub计划模式03

目次
3、包裝IBinder接口  -- 使用Proxy-Stub计划模式
EIT造型的双层组合 
4、 谁来写Proxy及Stub类呢?     -- 地头蛇(App开发者)自己写
范例
界说一个新接口: IPlayer
 撰写一个Stub类: PlayerStub
撰写mp3Binder类
撰写mp3RemoteService类

3、包裝IBinder接口  -- 使用Proxy-Stub计划模式



[*]采用Proxy-Stub计划模式将IBinder接口包装起来,让App与IBinder接口不再产生高度相依性。
https://i-blog.csdnimg.cn/direct/69312ecf57fe4cfb89cdbd3e2a36d218.png
[*]其将IBinder接口包装起来,转换出更好用的新接口:
https://i-blog.csdnimg.cn/direct/992f0fa7d1b445fab36935fd80587a5f.png
[*]Proxy类提供较好用的IA接口给Client使用。
[*]Stub类别则是屏蔽了Binder基类的onTransact()函数,然后将IA接口里的f1()和f2()函数界说为抽象函数。于是简化了App开发的负担:
https://i-blog.csdnimg.cn/direct/d01c50f604c24beabd16e4c40b129721.png
EIT造型的双层组合 

https://i-blog.csdnimg.cn/direct/8b7ca58375054748bab636addfe2f2ac.png
4、 谁来写Proxy及Stub类呢?     -- 地头蛇(App开发者)自己写

范例



[*]兹写一个App范例, 程序实行时出现画面如下:
https://i-blog.csdnimg.cn/direct/1dff499763b54e96979bd202fb861474.png


[*]在这个范例里,界说了一个IPlayer接口,然后规划了PlayerProxy和PlayerStub两的类,如下图:
https://i-blog.csdnimg.cn/direct/26f93af420e941fcb4f007cc7dcfdb0e.png
界说一个新接口: IPlayer

// IPlayer.java
package com.misoo.pkgx;
public interface IPlayer {
    void play();
    void stop();
    String getStatus();
}  撰写一个Stub类: PlayerStub

// PlayerStub.java
package com.misoo.pkgx;
import android.os.Binder;
import android.os.Parcel;
public abstract class PlayerStub extends Binder implements IPlayer{
    @Override
    public boolean onTransact(int code, Parcel data,Parcel reply, int flags) throws android.os.RemoteException {
      reply.writeString(data.readString()+ " mp3");
      if(code == 1) this.play();
      else if(code == 2) this.stop();
      return true;
    }

    public abstract void play();
    public abstract void stop();
    public abstract String getStatus();
} 撰写一个Proxy类: PlayerProxy
// PlayProxy.java
private class PlayerProxy implements IPlayer{
    private IBinder ib;
    private String mStatus;
    PlayerProxy(IBinder ibinder)
         { ib = ibinder; }

    public void play(){
      Parcel data = Parcel.obtain();
      Parcel reply = Parcel.obtain();
      data.writeString("playing");
      try { ib.transact(1, data, reply, 0);
            mStatus = reply.readString();
      } catch (Exception e) { e.printStackTrace(); }
    }

    public void stop(){
      Parcel data = Parcel.obtain();
      Parcel reply = Parcel.obtain();
      data.writeString("stop");
      try { ib.transact(2, data, reply, 0);
            mStatus = reply.readString();
      } catch (Exception e) { e.printStackTrace(); }
    }

    public String getStatus() { return mStatus; }
}
APP的代码
撰写mp3Binder类
 

// mp3Binder.java
// ……..
public class mp3Binder extends PlayerStub{
    private MediaPlayer mPlayer = null;
    private Context ctx;
    public mp3Binder(Context cx){ ctx= cx; }

    public void play(){
      if(mPlayer != null) return;
      mPlayer = MediaPlayer.create(ctx, R.raw.test_cbr);
      try { mPlayer.start();
      } catch (Exception e) {
            Log.e("StartPlay", "error: " + e.getMessage(), e); }}

    public void stop(){
      if (mPlayer != null)
            { mPlayer.stop(); mPlayer.release(); mPlayer = null; }
    }

    public String getStatus() { return null; }
} 撰写mp3RemoteService类
 

// mp3RemoteService.java
package com.misoo.pkgx;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class mp3RemoteService extends Service {
    private IBinder mBinder = null;
    @Override public void onCreate() {
      mBinder = new mp3Binder(getApplicationContext());
    }

    @Override
    public IBinder onBind(Intent intent) { return mBinder; }
}

// ac01.java
// ………
public class ac01 extends Activity implements OnClickListener {
    //……….
    private PlayerProxy pProxy = null;
    public void onCreate(Bundle icicle) {
      // ………
      startService(new Intent("com.misoo.pkgx.REMOTE_SERVICE"));
      bindService(new Intent("com.misoo.pkgx.REMOTE_SERVICE"),
      mConnection, Context.BIND_AUTO_CREATE); }
      private ServiceConnection mConnection = new ServiceConnection() {
            public void onServiceConnected(ComponentName className,IBinder ibinder)
                { pProxy = new PlayerProxy(ibinder); }
            public void onServiceDisconnected(ComponentName classNa){}
      };

    public void onClick(View v) {
      switch (v.getId()) {
            case 101: pProxy.play(); tv.setText(pProxy.getStatus());
                break;
            case 102: pProxy.stop(); tv.setText(pProxy.getStatus());
                break;
            case 103:
                unbindService(mConnection);
                stopService(new Intent("com.misoo.pkgx.REMOTE_SERVICE"));
                finish(); break;
      }
    }
}

[*]PlayerStub类将onTransact()函数潜伏起来,提供一个更具有美感、更密切的新接口给mp3Binder类使用。
[*]潜伏了onTransact()函数之后,mp3Binder类的开发者就不必费心去相识onTransact()函数了。于是, PlayerProxy与PlayerStub两个类遥遥相对,并且将IPC细节知识(例如transact()和onTransact()函数之参数等)包夹起来。
 
 


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 深入Android架构(从线程到AIDL)_21 IPC的Proxy-Stub计划模式03