iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android 进程间通信实现原理分析
  • 479
分享到

Android 进程间通信实现原理分析

进程进程间通信通信Android 2022-06-06 10:06:22 479人浏览 安东尼
摘要

Android Service是分为两种:  本地服务(Local Service): 同一个apk内被调用  远程服务(Remote Service):被另一个apk调用远程

Android Service是分为两种:
  本地服务(Local Service): 同一个apk内被调用
  远程服务(Remote Service):被另一个apk调用
远程服务需要借助aiDL来完成。

AIDL 是什么
  AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
  AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。
AIDL 的作用
  由于每个应用程序都运行在自己的进程空间,并且可以从应用程序UI运行另一个服务进程,而且经常会在不同的进程间传递对象。在Android平台,一个进程通常不能访问另一个进程的内存空间,所以要想对话,需要将对象分解成操作系统可以理解的基本单元,并且有序的通过进程边界。
  通过代码来实现这个数据传输过程是冗长乏味的,Android提供了AIDL工具来处理这项工作。
选择AIDL的使用场合
  官方文档特别提醒我们何时使用AIDL是必要的:只有你允许客户端从不同的应用程序为了进程间的通信而去访问你的service,以及想在你的service处理多线程
  如果不需要进行不同应用程序间的并发通信(IPC),you should create your interface by implementing a Binder;或者你想进行IPC,但不需要处理多线程的,则implement your interface using a Messenger。无论如何,在使用AIDL前,必须要理解如何绑定service——bindService。

下面将要讲到的这个例子来自:Http://www.cnblogs.com/lonkiss/arcHive/2012/10/23/2735548.html

下面用一个客户端Activity操作服务端Service播放音乐的实例演示AIDL的使用。

服务端代码结构(左)                                 客户端代码结构(右)
被标记的就是需要动手的。
服务端

新建一个android application project,命名为PlayerServer。 在res下的raw文件夹里面放入一个音乐文件,我这里放入的是Delta Goodrem的《Lost Without You》片段。如果不存在raw这个文件夹就自己新建一个,命名为raw。这个文件夹在raw文件夹下,与layout文件夹平级。raw中的文件遵守标识符的命名规则,不要出现中文和空格,多个单词可以用下划线连接。
  
新建一个IRemoteServiice.aidl 文件,加入如下代码
代码如下:
package pandafang.demo.playerserver;
interface IRemoteService {
 void play();
 void stop();
}

可见aidl文件的代码跟java的interface一样,但是aidl中不能加public等修饰符。Ctrl + S 保存后 ADT 会根据这个IRemoteService.aidl文件自动生成IRemoteService.java文件。如同R.java文件一样在“gen/包名”下,代码是自动生成的,不要手动修改。
  
接下来就是bound service的知识了。IRemoteService.java 中有一个Stub静态抽象类extends Binder implements IRemoteService。自己动手写一个PlayerService 用来播放音乐,播放音乐需要使用

android.media.MediaPlayer类。代码如下
代码如下:

public class PlayerService extends Service {
 public static final String TAG = "PlayerService";
 private MediaPlayer mplayer;
 @Override
 public IBinder onBind(Intent intent) {
  Log.i(TAG,"service onbind");
  if(mplayer==null){
   // 方法一说明
   // 此方法实例化播放器的同时指定音乐数据源 ,若用此方法在,mplayer.start() 之前不需再调用mplayer.prepare()
   // 官方文档有说明 :On success, prepare() will already have been called and must not be called again.
   // 译文:一旦create成功,prepare已被调用,勿再调用 。查看源代码可知create方法内部已经调用prepare方法。
   // 方法一开始
   // mplayer = MediaPlayer.create(this, R.raw.lost);
   // 方法一结束
   // 方法二说明
   // 若用此方法,在mplayer.start() 之前需要调用mplayer.prepare()
   // 方法二开始
   mplayer = new MediaPlayer();
   try {
    FileDescriptor fd = getResources().openRawResourceFd(R.raw.lost).getFileDescriptor(); // 获取音乐数据源
    mplayer.setDataSource(fd); // 设置数据源
    mplayer.setLooping(true); // 设为循环播放
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   // 方法二结束
   Log.i(TAG,"player created");
  }
  return mBinder;
 }
 // 实现aidl文件中定义的接口
 private IBinder mBinder = new IRemoteService.Stub() {
  @Override
  public void stop() throws RemoteException {
   try {
    if (mplayer.isPlaying()) {
     mplayer.stop();
    }
   } catch (Exception e) {
    // TODO: handle exception
    e.printStackTrace();
   }
  }
  @Override
  public void play() throws RemoteException {
   try {
    if (mplayer.isPlaying()) {
     return;
    }
    // start之前需要prepare。
    // 如果前面实例化mplayer时使用方法一,则第一次play的时候直接start,不用prepare。
    // 但是stop一次之后,再次play就需要在start之前prepare了。
    // 前面使用方法二 这里就简便了, 不用判断各种状况
    mplayer.prepare();
    mplayer.start();
   } catch (Exception e) {
    // TODO: handle exception
    e.printStackTrace();
   }
  }
 };
 @Override
 public boolean onUnbind(Intent intent) {
  if (mplayer != null) {
   mplayer.release();
  }
  Log.i(TAG,"service onUnbind");
  return super.onUnbind(intent);
 }
}

服务编写好以后,按照惯例在AndroidManifest.xml中加入声明,代码如下
代码如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="pandafang.demo.playerserver"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion ="8"
        android:targetSdkVersion="15" />
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <service android:name=".PlayerService" android:process=":remote">
            <intent-filter >
                <action android:name="com.example.playerserver.PlayerService"/>
            </intent-filter>
         </service>
    </application>
</manifest>

需要加入的只是<service>...</service>那段,要注意的是 android:process=":remote" 和 intent-filter 。
  运行服务端到设备上,准备给客户端调用
客户端
  新建一个android application project,命名为PlayerClient。将服务端放有aidl文件的包直接copy到客户
端src目录下,保留包中的aidl文件,其他删除。
 编写MainActivity.java 代码如下
代码如下:

public class MainActivity extends Activity {
 public static final String TAG = "MainActivity";
 // 服务端 AndroidManifest.xml中的intent-filter action声明的字符串
 public static final String ACTION = "com.example.playerserver.PlayerService";
 private Button playbtn, stopbtn;
 private IRemoteService mService;
 private boolean isBinded = false;
 private ServiceConnection conn = new ServiceConnection() {
  @Override
  public void onServiceDisconnected(ComponentName name) {
   isBinded = false;
   mService = null;
  }
  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
   mService = IRemoteService.Stub.asInterface(service);
   isBinded = true;
  }
 };
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        doBind();
        initViews();
    }
    private void initViews() {
     playbtn = (Button) findViewById(R.id.button1);
        stopbtn = (Button) findViewById(R.id.button2);
        playbtn.setOnClickListener(clickListener);
        stopbtn.setOnClickListener(clickListener);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
    @Override
    protected void onDestroy() {
  doUnbind();
     super.onDestroy();
    }
    public void doBind() {
     Intent intent = new Intent(ACTION);
     bindService(intent, conn, Context.BIND_AUTO_CREATE);
    }
    public void doUnbind() {
     if (isBinded) {
      unbindService(conn);
     & nbsp;   mService = null;
         isBinded = false;
     }
    }
    private OnClickListener clickListener = new OnClickListener() {
  @Override
  public void onClick(View v) {
   if (v.getId() == playbtn.getId()) {
    // play
    Log.i(TAG,"play button clicked");
    try {
     mService.play();
    } catch (RemoteException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   } else {
    // stop
    Log.i(TAG,"stop button clicked");
    try {
     mService.stop();
    } catch (RemoteException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  }
 };
}

MainActivity是根据向导自动生成的,不需要在AndroidManifest.xml中注册声明了
运行客户端到设备,按下按钮可以播放/停止 效果如图

如果想对更加详细的实现原理进行研究,可以参见这篇文章:
http://www.cnblogs.com/over140/archive/2011/03/08/1976890.html

您可能感兴趣的文章:Android进程通信之Messenger和AIDL使用详解Android IPC机制利用Messenger实现跨进程通信深入理解Android中的Handler异步通信机制深入Android Handler与线程间通信ITC的详解Android Handler主线程和一般线程通信的应用分析Android Socket通信详解Android编程之客户端通过socket与服务器通信的方法Android单片机与蓝牙模块通信实例代码Android之网络通信案例分析Android网络编程之UDP通信模型实例Android开发使用Messenger及Handler进行通信的方法示例


--结束END--

本文标题: Android 进程间通信实现原理分析

本文链接: https://www.lsjlt.com/news/27593.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android 进程间通信实现原理分析
    Android Service是分为两种:  本地服务(Local Service): 同一个apk内被调用  远程服务(Remote Service):被另一个apk调用远程...
    99+
    2022-06-06
    进程 进程间通信 通信 Android
  • Android Messenger实现进程间通信及其原理
    前言 之前分析Android消息机制的源码时,曾遇到过replyTo、IMessenger等属性字段,当时只是说这些字段用于进程间通信,并未作深入分析。今天这篇文字就来演示一下使用M...
    99+
    2022-11-12
  • Android AIDL实现进程间通信探索
    前言:       前面总结了程序间共享数据,可以使用ContentProvider也可以使用SharedPreferenc...
    99+
    2022-06-06
    进程 aidl 进程间通信 通信 Android
  • Android Messenger实现进程间双向通信
    简介 Messenger是安卓进程间通信 (IPC) 最为简单的方式,可以实现进程间双向通信。详见官网介绍 代码实现 服务端应用实现 MessengerService接收客户端发送的...
    99+
    2022-11-12
  • Android中怎么实现进程间通信
    这篇文章给大家介绍Android中怎么实现进程间通信,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。由于android系统中应用程序之间不能共享内存。因此,在不同应用程序之间交互数据(跨进程通讯)就稍微麻烦一些。进程间通...
    99+
    2023-06-04
  • Android中使用 Messenger 实现进程间通信小案例与分析说明
    文章目录Messenger 是什么Messenger 底层实现Messenger 使用说明案例实现说明新建一个项目创建 ServiceServi...
    99+
    2022-06-06
    messenger 进程 进程间通信 通信 Android
  • 分析CmProcess跨进程通信的实现
    目录一、基础知识准备1.1、多进程1.2、Bundle类二、代码解析2.1、AIDL接口2.2、启动分析三、EventReceiver四、ServiceManagerNative五、...
    99+
    2022-11-12
  • Python中进程间通信的示例分析
    这篇文章给大家分享的是有关Python中进程间通信的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。进程概述进程(Process)是计算机中已运行程序的实体。进程与程序不同,程序本身只是指令、数据及器组织形...
    99+
    2023-06-29
  • Electron进程间通信的实现
    目录主进程与渲染进程之间通信ipc模块 + window.webContentsremote模块渲染进程之间通信使用Electron开发出来的桌面应用都是多进程的,其中包含了一个主进...
    99+
    2022-11-13
  • 详解Android 进程间通信的几种实现方式
    一、概述 由于应用程序之间不能共享内存。在不同应用程序之间交互数据(跨进程通讯),在Android SDK中提供了4种用于跨进程通讯的方式。 这4种方式正好对应于android...
    99+
    2022-06-06
    进程 进程间通信 通信 Android
  • 怎么在Android中使用AIDL实现进程间通信
    怎么在Android中使用AIDL实现进程间通信?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、概述AIDL 意思即 Android Interface Definiti...
    99+
    2023-05-30
    android aidl
  • python多进程实现进程间通信实例
    python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。Python提供了非常好用的多进程包multiprocessing,只需要定义一个...
    99+
    2022-06-04
    进程 实例 通信
  • golang进程间通信怎么实现
    在Go语言中,有多种方式可以实现进程间通信。以下是一些常见的方法: 使用管道(Pipe):管道是进程间通信的一种简单而有效的方式...
    99+
    2023-10-25
    golang
  • Linux进程间通信怎么实现
    这篇文章主要讲解了“Linux进程间通信怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux进程间通信怎么实现”吧!共享内存共享内存可以说是最有用的进程间通信方式,也是最快的IP...
    99+
    2023-07-05
  • Electron进程间通信如何实现
    今天小编给大家分享一下Electron进程间通信如何实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。使用Electron开...
    99+
    2023-06-30
  • Android Handler 机制实现原理分析
    handler在安卓开发中是必须掌握的技术,但是很多人都是停留在使用阶段。使用起来很简单,就两个步骤,在主线程重写handler的handleMessage( )方法,在工作线...
    99+
    2022-06-06
    handler Android
  • Android 通过Messager与Service实现进程间双向通信案例详解
    目录Messenger使用步骤Service代码客户端代码分析结果注意事项Android中的Service和其调用者既可以在同一个App中,也可以在不同的App。如果Service在...
    99+
    2022-11-12
  • Android 图文详解Binder进程通信底层原理
    目录🔥 什么是进程间通信🔥 什么是 Binder🔥 Android 中 IPC 的方式🔥 Binder 优势€...
    99+
    2022-11-12
  • Redis集群节点通信过程/原理流程分析
    目录简介通信流程Gossip消息消息流程消息格式节点选择1.选择发送消息的节点数量2.消息数据量其他网址简介         本文介绍Redi...
    99+
    2022-11-13
  • express实现中间件的原理分析
    小编给大家分享一下express实现中间件的原理分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!简介中间件机制可以让我们在一个给定的流程中添加一个处理步骤,从而对这个流程的输入或者输出产...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作