当前位置: 首页 > article >正文

深入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接口不再产生高度相依性。
  • 其将IBinder接口包装起来,转换出更好用的新接口:
  • Proxy类提供较好用的IA接口给Client使用。
  • Stub类别则是屏蔽了Binder基类的onTransact()函数,然后将IA接口里的f1()和f2()函数定义为抽象函数。于是简化了App开发的负担:
EIT造型的双层组合 

4、 谁来写Proxy及Stub类呢?     -- 地头蛇(App开发者)自己写

范例
  • 兹写一个App范例, 程序执行时出现画面如下:

  • 在这个范例里,定义了一个IPlayer接口,然后规划了PlayerProxy和PlayerStub两的类,如下图:
定义一个新接口: 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()函数之参数等)包夹起来。

 

 


http://www.kler.cn/a/487882.html

相关文章:

  • Python爬虫应用领域
  • Figma如何装中文字体-PingFang苹方字体、Alibaba PuHuiTi阿里普惠
  • 用 Python 绘制可爱的招财猫
  • IWOA-GRU和GRU时间序列预测(改进的鲸鱼算法优化门控循环单元)
  • 推动多语言语音科技迈向新高度:INTERSPEECH 2025 ML-SUPERB 2.0 挑战赛
  • Selenium 的四种等待方式及使用场景
  • 【C++】C++11(二)
  • 通过 crontab 每天定时启动一个 Java JAR 包并调用特定的 `main` 方法
  • LeetCode599 两个列表的最小索引总和
  • jenkins 调用bat脚本
  • 计算机网络之---TCP/IP四层模型
  • 算法-cpp入门语法练习题
  • ubuntu22.04 的录屏软件有哪些?
  • 集合——数据结构
  • linux-磁盘io性能指标!
  • Golang的代码压缩技术应用案例分析与研究实践
  • 网络基础知识--11
  • Kali系统(Debian 10.3) 遇到的问题
  • MySQL_约束
  • 夜话卡尔曼滤波(2) - 变量定义
  • Euler 21.10安装oracle 19.22单机安装
  • C#语言的数据结构
  • python-42-使用selenium-wire爬取微信公众号下的所有文章列表
  • Perl语言的软件开发工具
  • 设计一个利用事务特性可以阻塞线程的排他锁,并且通过注解和 AOP 来实现
  • 【C++/控制台】2048小游戏