news 2026/8/28 15:24:38

Android 多进程开发 - 服务端死亡回调、服务端与客户端的线程环境、oneway 关键字

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Android 多进程开发 - 服务端死亡回调、服务端与客户端的线程环境、oneway 关键字

一、服务端死亡回调

  • 在绑定服务端时,可以获取服务端时的 Binder 对象,调用 Binder 对象的 linkToDeath 方法,注册死亡回调,监听服务端时是否挂了
privateIMyAidlInterfacemyAidlInterface;privatebooleanisBound=false;privatefinalIBinder.DeathRecipientdeathRecipient=newIBinder.DeathRecipient(){@OverridepublicvoidbinderDied(){Log.i(TAG,"检测到服务端进程死亡");}};privateServiceConnectionconnection=newServiceConnection(){@OverridepublicvoidonServiceConnected(ComponentNamename,IBinderservice){Log.i(TAG,"服务连接成功");myAidlInterface=IMyAidlInterface.Stub.asInterface(service);try{service.linkToDeath(deathRecipient,0);}catch(RemoteExceptione){e.printStackTrace();}isBound=true;}@OverridepublicvoidonServiceDisconnected(ComponentNamename){Log.i(TAG,"服务连接断开");myAidlInterface=null;isBound=false;// 系统会处理 unlinkToDeath、unbindService}};
  • 触发 onServiceDisconnected 回调,系统会处理 unlinkToDeath、unbindService,不需要手动调用,详见源码
// 1. doDeath 方法源码publicvoiddoDeath(ComponentNamename,IBinderservice){synchronized(this){ConnectionInfoold=mActiveConnections.get(name);if(old==null||old.binder!=service){// Death for someone different than who we last// reported... just ignore it.return;}mActiveConnections.remove(name);old.binder.unlinkToDeath(old.deathMonitor,0);}mConnection.onServiceDisconnected(name);}
// doDeath 方法中的清理逻辑mActiveConnections.remove(name);old.binder.unlinkToDeath(old.deathMonitor,0);
// 2. doConnected 方法publicvoiddoConnected(ComponentNamename,IBinderservice,booleandead){ServiceDispatcher.ConnectionInfoold;ServiceDispatcher.ConnectionInfoinfo;synchronized(this){if(mForgotten){// We unbound before receiving the connection; ignore// any connection received.return;}old=mActiveConnections.get(name);if(old!=null&&old.binder==service){// Huh, already have this one. Oh well!return;}if(service!=null){// A new service is being connected... set it all up.info=newConnectionInfo();info.binder=service;info.deathMonitor=newDeathMonitor(name,service);try{service.linkToDeath(info.deathMonitor,0);mActiveConnections.put(name,info);}catch(RemoteExceptione){// This service was dead before we got it... just// don't do anything with it.mActiveConnections.remove(name);return;}}else{// The named service is being disconnected... clean up.mActiveConnections.remove(name);}if(old!=null){old.binder.unlinkToDeath(old.deathMonitor,0);}}// If there was an old service, it is now disconnected.if(old!=null){mConnection.onServiceDisconnected(name);}if(dead){mConnection.onBindingDied(name);}else{// If there is a new viable service, it is now connected.if(service!=null){mConnection.onServiceConnected(name,service);}else{// The binding machinery worked, but the remote returned null from onBind().mConnection.onNullBinding(name);}}}
// doConnected 方法中的清理逻辑if(old!=null){old.binder.unlinkToDeath(old.deathMonitor,0);}

二、服务端与客户端的线程环境

1、服务端
  1. AIDL 接口,在主线程执行(无论客户端是在主线程调用,还是在子线程调用)
privatefinalIMyAidlInterface.Stubbinder=newIMyAidlInterface.Stub(){@Overridepublicintadd(inta,intb)throwsRemoteException{// Binder 线程returna+b;}}
  1. DeathRecipient 回调,在 Binder 线程执行
IBinder.DeathRecipientdr=newDeathRecipient(){@OverridepublicvoidbinderDied(){// Binder 线程}};
2、客户端
  1. ServiceConnection 回调,在主线程执行
privateServiceConnectionconnection=newServiceConnection(){@OverridepublicvoidonServiceConnected(ComponentNamename,IBinderservice){// 主线程}@OverridepublicvoidonServiceDisconnected(ComponentNamename){// 主线程}};
  1. DeathRecipient 回调,在 Binder 线程执行
privatefinalIBinder.DeathRecipientdeathRecipient=newIBinder.DeathRecipient(){@OverridepublicvoidbinderDied(){// 主线程}};
  1. AIDL 接口调用,调用前后都是在调用者线程执行
try{// 主线程intresult=myAidlInterface.add(5,3);Log.i(TAG,"add result: "+result);// 主线程}catch(RemoteExceptione){e.printStackTrace();Log.e(TAG,"add method error: "+e.getMessage());}
newThread(()->{try{// 子线程intresult=myAidlInterface.add(5,3);Log.i(TAG,"add result: "+result);// 子线程}catch(RemoteExceptione){e.printStackTrace();Log.e(TAG,"add method error: "+e.getMessage());}}).start();
  1. AIDL 接口回调,在主线程执行(无论客户端是在主线程注册,还是在子线程注册)
callback=newIPlayerCallback.Stub(){@OverridepublicvoidonSongChanged(StringsongName)throwsRemoteException{// 主线程Log.i(TAG,"onSongChanged: "+songName);}@OverridepublicvoidonPlayStateChanged(booleanisPlaying)throwsRemoteException{// 主线程Log.i(TAG,"onPlayStateChanged: "+isPlaying);}};try{myAidlInterface.registerCallback(callback);Log.i(TAG,"registerCallback method success");}catch(RemoteExceptione){e.printStackTrace();Log.e(TAG,"registerCallback method error: "+e.getMessage());}
newThread(()->{callback=newIPlayerCallback.Stub(){@OverridepublicvoidonSongChanged(StringsongName)throwsRemoteException{// 主线程Log.i(TAG,"onSongChanged: "+songName);}@OverridepublicvoidonPlayStateChanged(booleanisPlaying)throwsRemoteException{// 主线程Log.i(TAG,"onPlayStateChanged: "+isPlaying);}};try{myAidlInterface.registerCallback(callback);Log.i(TAG,"registerCallback method success");}catch(RemoteExceptione){e.printStackTrace();Log.e(TAG,"registerCallback method error: "+e.getMessage());}}).start();

三、oneway 关键字

1、基本介绍
  • oneway 关键字修饰的方法,客户端调用后立即返回,不等待服务端执行完成
onewayvoiddoSomething();
2、注意事项
  1. oneway 方法不能有返回值,否则编译报错
onewayStringdoSomething();
# 输出结果 oneway method 'doSomething' cannot return a value
  1. oneway 方法的参数可以用 in 修饰
onewayvoiddoSomething(inbyte[]data);
  1. oneway 方法的参数不能用 out 或 inout 修饰,否则编译报错
onewayvoiddoSomething(outbyte[]data);
# 输出结果 oneway method 'doSomething' cannot have out parameters
onewayvoiddoSomething(inoutbyte[]data);
# 输出结果 oneway method 'doSomething' cannot have out parameters
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/28 15:24:02

Spec Kit “从零到专家”

下面是一份**按 Spec Kit 官方仓库文档/模板(github/spec-kit)**整理的「从零到专家」分阶段使用指南:你可以把它当成一条学习路线(每一阶段都有“目标—动作—产物—常见坑”),一路用到熟练掌握 Spec-Driven Development(SDD)的工作流。 你要掌握的整体心智模型 Spec…

作者头像 李华
网站建设 2026/8/21 0:55:25

除了OpenClaw大龙虾,还有6只“小龙虾“:什么是Nanobot:Py开发者,什么是NanoClaw:多智能体, 什么是IronClaw:安全,什么是ZeroClaw:树莓派,什么是PicoCla

OpenClaw生态全家桶:除了"大龙虾",这6只"小龙虾"框架更轻更强|Nanobot/NanoClaw/IronClaw/ZeroClaw/PicoClaw/TinyClaw深度评测 摘要 OpenClaw主框架已斩获24万 GitHub Stars,但其生态圈的6个轻量级衍生项目…

作者头像 李华
网站建设 2026/8/28 8:12:00

AI时代的技术民主化:为什么文科生可能成为最大受益者?

✨道路是曲折的,前途是光明的!📝 专注C/C、Linux编程与人工智能领域,分享学习笔记!🌟 感谢各位小伙伴的长期陪伴与支持,欢迎文末添加好友一起交流!当技术门槛被无限降低,…

作者头像 李华
网站建设 2026/8/27 23:24:21

基于MATLAB的PAM调制直调直检信号色散补偿实现

一、系统架构设计 #mermaid-svg-UF7XkgEoZCCxxyfp{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-UF7XkgEo…

作者头像 李华
网站建设 2026/8/21 7:22:16

蓝易云 :Greenplum实用技巧

蓝易云:Greenplum 实用技巧(上手就能提效)🚀 Greenplum 本质是 MPP(大规模并行处理)共享无架构:数据分布在多个 Segment 上并行扫描、并行聚合,所以“跑得快”往往不是靠堆硬件&…

作者头像 李华
网站建设 2026/8/21 7:28:56

蓝易云 :Python基本文件操作及os库

蓝易云:Python 基本文件操作与 os 库(实战向)📁🐍Python 的文件操作本质是:把磁盘上的“字节流”通过 打开(open) → 读写(read/write) → 关闭(c…

作者头像 李华