深入Android架构(从线程到AIDL)_20 IPC的Proxy-Stub设计模式02

2、 IBinder接口的一般用途

前言

一般用途
  • Android的IPC框架仰赖单一的IBinder接口。此时Client端调用IBinder接口的transact()函数,透过IPC机制而调用到远方(Remote)的onTransact()函数。
  • 在Java层框架里, IBinder接口实现于Binder基类,如下图:
  • myActivity调用IBinder接口,执行myBinder的onTransact()函数,可送信息给myService去播放mp3音乐,如下图:
  • myService也能送Broadcast信息给myActivity,将字符串显示于画面上:

 

// myActivity.java
// ………
public class myActivity extends Activity implements OnClickListener {private final int WC = LinearLayout.LayoutParams.WRAP_CONTENT;private final int FP = LinearLayout.LayoutParams.FILL_PARENT;private Button btn, btn2, btn3;public TextView tv;private IBinder ib = null;private final String MY_S_EVENT = new String("com.misoo.pk01.myService.MY_S_EVENT");protected final IntentFilter filter=new IntentFilter(MY_S_EVENT);private BroadcastReceiver receiver=new myIntentReceiver();public void onCreate(Bundle icicle) {super.onCreate(icicle);LinearLayout layout = new LinearLayout(this);layout.setOrientation(LinearLayout.VERTICAL);btn = new Button(this); btn.setId(101); btn.setText("play");btn.setBackgroundResource(R.drawable.heart);btn.setOnClickListener(this);LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(80, 50);param.topMargin = 10; layout.addView(btn, param);btn2 = new Button(this);btn2.setId(102);btn2.setText("stop");btn2.setBackgroundResource(R.drawable.heart);btn2.setOnClickListener(this);layout.addView(btn2, param);btn3 = new Button(this);btn3.setId(103); btn3.setText("exit");btn3.setBackgroundResource(R.drawable.cloud);btn3.setOnClickListener(this);layout.addView(btn3, param);tv = new TextView(this); tv.setText("Ready");LinearLayout.LayoutParams param2 = newLinearLayout.LayoutParams(FP, WC);param2.topMargin = 10;layout.addView(tv, param2);setContentView(layout);//---------------------------------registerReceiver(receiver, filter);//------------------------------------------------------bindService( new Intent("com.misoo.pk01.REMOTE_SERVICE"),mConnection, Context.BIND_AUTO_CREATE);}btn3 = new Button(this);btn3.setId(103); btn3.setText("exit");btn3.setBackgroundResource(R.drawable.cloud);btn3.setOnClickListener(this);layout.addView(btn3, param);tv = new TextView(this); tv.setText("Ready");LinearLayout.LayoutParams param2 = newLinearLayout.LayoutParams(FP, WC);param2.topMargin = 10;layout.addView(tv, param2);setContentView(layout);//---------------------------------registerReceiver(receiver, filter);//------------------------------------------------------bindService( new Intent("com.misoo.pk01.REMOTE_SERVICE"),mConnection, Context.BIND_AUTO_CREATE) );
}private ServiceConnection mConnection =new ServiceConnection() {@Override public void onServiceConnected(ComponentName className, IBinder ibinder) {ib = ibinder;}@Override public void onServiceDisconnected(ComponentName name) { }
};public void onClick(View v) {switch (v.getId()) {case 101: // Play ButtonParcel data = Parcel.obtain();Parcel reply = Parcel.obtain();try { ib.transact(1, data, reply, 0);} catch (Exception e) { e.printStackTrace(); }break;case 102: // Stop Buttondata = Parcel.obtain(); reply = Parcel.obtain();try { ib.transact(2, data, reply, 0);} catch (Exception e) { e.printStackTrace(); }break;case 103: finish(); break;}
}
  • 其中的代码:
    case 101: // Play Button
            //…..
            ib.transact(1, data, reply, 0);
    case 102: // Stop Button
            // …..
            ib.transact(2, data, reply, 0);
  • 就是对<Play>和<Stop>两个功能进行”编码” 的动作。
  • 编好码之后,就将这编码值当做第1个参数传给IBinder接口的transact()函数。
  • 于是编码值就跨进程地传递到myBinder类里的onTransact()函数了。
     
class myIntentReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {int bn = intent.getIntExtra("key",-1);if(bn == 0)tv.setText("Playing");elsetv.setText("Stop.");}
}// myService.java
// ……..
public class myService extends Service implements Runnable {private IBinder mBinder = null;private Thread th1;public static Handler h;private MediaPlayer mPlayer = null;public static Context ctx;private final String MY_S_EVENT = new String("com.misoo.pk01.myService.MY_S_EVENT");@Override public void onCreate() {super.onCreate(); ctx = this;mBinder = new myBinder();// 诞生一个子线程及其MQ; 等待Messageth1 = new Thread(this);th1.start();}@Overridepublic IBinder onBind(Intent intent) { return mBinder; }public void run() {Looper.prepare();h = new EventHandler(Looper.myLooper());Looper.loop();}//---------------------------------------class EventHandler extends Handler {public EventHandler(Looper looper) { super(looper); }public void handleMessage(Message msg) {String obj = (String)msg.obj;if(obj.contains("play")) {if(mPlayer != null) return;//----------------------------------Intent in = new Intent(MY_S_EVENT);in.putExtra("key", 0);ctx.sendBroadcast(in);//----------------------------------mPlayer = MediaPlayer.create(ctx, R.raw.dreamed);try { mPlayer.start();} catch (Exception e) {Log.e("Play", "error: " + e.getMessage(), e);}}else if(obj.contains("stop")) {if (mPlayer != null) {Intent in = new Intent(MY_S_EVENT);in.putExtra("key", 1);ctx.sendBroadcast(in);//----------------------------------mPlayer.stop(); mPlayer.release();mPlayer = null;}}}}
}// myBinder.java
// …….
public class myBinder extends Binder{@Override public boolean onTransact( int code, Parcel data, Parcel reply, int flags) throws android.os.RemoteException {switch( code ){case 1:// 将Message丢到子线程的MQ to play MP3String obj = "play";Message msg = myService.h.obtainMessage(1,1,1,obj);myService.h.sendMessage(msg);break;case 2:// 将Message丢到子线程的MQ to stop playingobj = "stop";msg = myService.h.obtainMessage(1,1,1,obj);myService.h.sendMessage(msg);break;}return true;}
}
  • 其代码就是对code进行“译码”动作。
  • 如果code值為1就執行<Play>動作;如果code值為2就執行<Stop>動作

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/66802.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ Json库的使用

1.Json库的使用&#xff0c;包含C Json的创建、读写、字符串Json互转等&#xff0c;覆盖日常使用场景 前提&#xff1a;按照参考的文章部署好nlohmann/json 上代码 #include <iostream> #include <fstream> #include "nlohmann/json.hpp" using json n…

初学stm32 --- ADC单通道采集

目录 ADC寄存器介绍&#xff08;F1&#xff09; ADC控制寄存器 1(ADC_CR1) ADC控制寄存器 2(ADC_CR2) ADC采样时间寄存器1(ADC_SMPR1) ADC采样时间寄存器2(ADC_SMPR2) ADC规则序列寄存器 1(ADC_SQR1) ADC规则序列寄存器 2(ADC_SQR2) ADC规则序列寄存器 3(ADC_SQR3) AD…

FPGA技术的深度理解

目录 引言 FPGA的基本原理 结构组成 工作原理 FPGA的设计流程 设计阶段 编程阶段 实现阶段 FPGA的应用领域 FPGA编程技巧和示例代码 编程技巧 示例代码 结论 引言 FPGA&#xff08;现场可编程门阵列&#xff09;是一种可编程的集成电路&#xff0c;它允许用户根据…

@SneakyThrows 注解详解

SneakyThrows 注解详解 1. 基本介绍 SneakyThrows 是 Lombok 提供的注解&#xff0c;用于简化异常处理&#xff0c;自动生成 try-catch 代码块&#xff0c;将检查型异常转换为非检查型异常。 2. 使用对比 2.1 传统写法 public String readFile(String path) {try {return …

【经典神经网络架构解析篇】【1】LeNet网络详解:模型结构解析、优点、实现代码

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

qml SpringAnimation详解

1. 概述 SpringAnimation 是 Qt Quick 中用于模拟弹簧效果的动画类。它通过模拟物体在弹簧力作用下的反应&#xff0c;产生一种振荡的动画效果&#xff0c;常用于模拟具有自然回弹、弹性和振动的动态行为。这种动画效果在 UI 中广泛应用&#xff0c;特别是在拖动、拉伸、回弹等…

day03-前端Web-Vue3.0基础

目录 前言1. Vue概述2. 快速入门2.1 需求2.2 步骤2.3 实现 3. Vue指令3.1 介绍3.2 v-for3.2.1 介绍3.2.2 演示3.2.3 v-for的key3.2.4 案例-列表渲染 3.3 v-bind3.3.1 介绍3.3.2 演示3.3.3 案例-图片展示 3.4 v-if & v-show3.4.1 介绍3.4.2 案例-性别职位展示 3.6 v-model3.…

Jenkins pipeline 发送邮件及包含附件

Jenkins pipeline 发送邮件及包含附件 设置邮箱开启SMTP服务 此处适用163 邮箱 开启POP3/SMTP服务通过短信获取TOKEN &#xff08;保存TOKEN, 后面Jenkins会用到&#xff09; Jenkins 邮箱设置 安装 Build Timestamp插件 设置全局凭证 Dashboard -> Manage Jenkins …

JSON.stringify 实现深度克隆的缺陷

在前端开发中&#xff0c;深克隆&#xff08;Deep Clone&#xff09;和浅克隆&#xff08;Shallow Clone&#xff09;是常见的操作。浅克隆和深克隆的区别主要体现在对象内部嵌套对象的处理方式上。 1. 浅克隆&#xff08;Shallow Clone&#xff09; 浅克隆是指创建一个新对象…

【软考】软件设计师

「学习路线」&#xff08;推荐该顺序学习&#xff0c;按照先易后难排序&#xff09; 1、上午题—计算机系统&#xff08;5~6分&#xff09;[1.8; ] 2、上午题—程序设计语言&#xff08;固定6分&#xff09;[1.9; ] 3、下午题—试题一&#xff08;15分&#xff09; 4、上午题—…

python学opencv|读取图像(二十九)使用cv2.getRotationMatrix2D()函数旋转缩放图像

【1】引言 前序已经学习了如何平移图像&#xff0c;相关文章链接为&#xff1a; python学opencv|读取图像&#xff08;二十七&#xff09;使用cv2.warpAffine&#xff08;&#xff09;函数平移图像-CSDN博客 在此基础上&#xff0c;我们尝试旋转图像的同时缩放图像。 【2】…

初学stm32 --- DAC输出

目录 DAC寄存器介绍&#xff08;F1&#xff09; DAC控制寄存器(DAC_CR) DAC通道1的12位右对齐数据保持寄存器(DAC_DHR12R1) DAC软件触发寄存器(DAC_SWTRIGR) DAC输出实验配置步骤 相关HAL库函数介绍 关键结构体介绍&#xff08;F1&#xff09; DAC寄存器介绍&#xff08;F1&…

Stable diffusion的SDXL模型,针不错!(含实操)

与之前的SD1.5大模型不同&#xff0c;这次的SDXL在架构上采用了“两步走”的生图方式&#xff1a; 以往SD1.5大模型&#xff0c;生成步骤为 Prompt → Base → Image&#xff0c;比较简单直接&#xff1b;而这次的SDXL大模型则是在中间加了一步 Refiner。Refiner的作用是什么呢…

知道蛋白uniprot id 进行VFDB注释

https://blog.csdn.net/missinghead/article/details/135699418 【生物信息】VFDB数据库预测毒力因子-CSDN博客 知道蛋白uniprot id 提取蛋白的fasta格式序列&#xff1a;现在uniprot网站下载物种所有蛋白序列文件 conda create -n kp_proteomic conda activate kp_proteomic…

51单片机——串口通信(重点)

1、通信 通信的方式可以分为多种&#xff0c;按照数据传送方式可分为串行通信和并行通信&#xff1b; 按照通信的数据同步方式&#xff0c;可分为异步通信和同步通信&#xff1b; 按照数据的传输方向又可分为单工、半双工和全双工通信 1.1 通信速率 衡量通信性能的一个非常…

【SpringAOP】Spring AOP 底层逻辑:切点表达式与原理简明阐述

前言 &#x1f31f;&#x1f31f;本期讲解关于spring aop的切面表达式和自身实现原理介绍~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &am…

Objective-C语言的软件工程

Objective-C语言的软件工程探讨 引言 在软件工程的领域中&#xff0c;编程语言的选择是至关重要的。Objective-C&#xff0c;作为一种为苹果公司的macOS和iOS操作系统而开发的编程语言&#xff0c;凭借其灵活性和强大的功能被广泛应用于应用开发。然而&#xff0c;随着Swift等…

GO通过SMTP协议发送邮件

什么是SMTP协议 SMTP&#xff08;Simple Mail Transfer Protocol&#xff0c;简单邮件传输协议&#xff09;是用于发送邮件的协议。当一个邮件服务器需要发送邮件给另一个邮件服务器时&#xff0c;它会使用SMTP协议与目标服务器建立连接&#xff0c;并传输邮件内容。SMTP协议的…

windows下,golang+vscode+delve 远程调试

1 先在远程服务器安装golang和delve golang的安装&#xff0c;通过官网直接下载安装包安装接口 go install github.com/go-delve/delve/cmd/dlvlatest 如果dlv和golang版本不匹配&#xff0c;这里把latest换成匹配的版本&#xff0c;比如1.20.0 2 编译带调试信息的程序 go bu…

Linux之线程池与单例模式

目录 线程池 线程池代码 单例模式 饿汉模式单例模式 懒汉模式单例模式 在前几期&#xff0c;我们已经学习了多线程的创建和控制&#xff0c;学习了多线程中的同步和互斥&#xff0c;学习了多线程中的条件变量和信号量&#xff0c;基于此我们实现了基于阻塞队列和基于环形队…