android 多进程 Binder AIDL Service
本文參考http://blog.csdn.net/saintswordsman/article/details/5130947
android的多进程是通过Binder来实现的,一个类,继承了Binder,那么它的对象就能够被远程的进程使用了(前提是远程进程获取了这个类的对象【对象的引用】,至于如怎样获得看下文),怎么使用呢?在Android中, 则採用AIDL(Android InterfaceDefinition Language:接口定义语言)方式实现。所以我们必须写后缀为.aidl的文件。.aidl文件放在src以下,刷新一下就会生成同名的.java文件
文件:forActivity.aidl
- package com.styleflying.AIDL;
- interface forActivity {
- void performAction();
- }
文件:forService.aidl
- package com.styleflying.AIDL;
- import com.styleflying.AIDL.forActivity;
- interface forService {
- void registerTestCall(forActivity cb);
- void invokCallBack();
- }
这两个文件和Java文件放置的地方一样,看包名。
在Eclipse中它们将被自己主动编译为forActivity.java和forService.java。它们存放在gen文件夹下。
为了方便手头无法演练的读者。代码贴上,不用细看。
文件forActivity.java:
- /*
- * This file is auto-generated. DO NOT MODIFY.
- * Original file: D://workspace//AIDLTest//src//com//styleflying//AIDL//forActivity.aidl
- */
- package com.styleflying.AIDL;
- import java.lang.String;
- import android.os.RemoteException;
- import android.os.IBinder;
- import android.os.IInterface;
- import android.os.Binder;
- import android.os.Parcel;
- public interface forActivity extends android.os.IInterface
- {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends android.os.Binder implements com.styleflying.AIDL.forActivity
- {
- private static final java.lang.String DESCRIPTOR = "com.styleflying.AIDL.forActivity";
- /** Construct the stub at attach it to the interface. */
- public Stub()
- {
- this.attachInterface(this, DESCRIPTOR);
- }
- /**
- * Cast an IBinder object into an forActivity interface,
- * generating a proxy if needed.
- */
- public static com.styleflying.AIDL.forActivity asInterface(android.os.IBinder obj)
- {
- if ((obj==null)) {
- return null;
- }
- android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
- if (((iin!=null)&&(iin instanceof com.styleflying.AIDL.forActivity))) {
- return ((com.styleflying.AIDL.forActivity)iin);
- }
- return new com.styleflying.AIDL.forActivity.Stub.Proxy(obj);
- }
- public android.os.IBinder asBinder()
- {
- return this;
- }
- @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
- {
- switch (code)
- {
- case INTERFACE_TRANSACTION:
- {
- reply.writeString(DESCRIPTOR);
- return true;
- }
- case TRANSACTION_performAction:
- {
- data.enforceInterface(DESCRIPTOR);
- this.performAction();
- reply.writeNoException();
- return true;
- }
- }
- return super.onTransact(code, data, reply, flags);
- }
- private static class Proxy implements com.styleflying.AIDL.forActivity
- {
- private android.os.IBinder mRemote;
- Proxy(android.os.IBinder remote)
- {
- mRemote = remote;
- }
- public android.os.IBinder asBinder()
- {
- return mRemote;
- }
- public java.lang.String getInterfaceDescriptor()
- {
- return DESCRIPTOR;
- }
- public void performAction() throws android.os.RemoteException
- {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_performAction, _data, _reply, 0);
- _reply.readException();
- }
- finally {
- _reply.recycle();
- _data.recycle();
- }
- }
- }
- static final int TRANSACTION_performAction = (IBinder.FIRST_CALL_TRANSACTION + 0);
- }
- public void performAction() throws android.os.RemoteException;
- }
文件forService.java:
- /*
- * This file is auto-generated. DO NOT MODIFY.
- * Original file: D://workspace//AIDLTest//src//com//styleflying//AIDL//forService.aidl
- */
- package com.styleflying.AIDL;
- import java.lang.String;
- import android.os.RemoteException;
- import android.os.IBinder;
- import android.os.IInterface;
- import android.os.Binder;
- import android.os.Parcel;
- public interface forService extends android.os.IInterface
- {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends android.os.Binder implements com.styleflying.AIDL.forService
- {
- private static final java.lang.String DESCRIPTOR = "com.styleflying.AIDL.forService";
- /** Construct the stub at attach it to the interface. */
- public Stub()
- {
- this.attachInterface(this, DESCRIPTOR);
- }
- /**
- * Cast an IBinder object into an forService interface,
- * generating a proxy if needed.
- */
- public static com.styleflying.AIDL.forService asInterface(android.os.IBinder obj)
- {
- if ((obj==null)) {
- return null;
- }
- android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
- if (((iin!=null)&&(iin instanceof com.styleflying.AIDL.forService))) {
- return ((com.styleflying.AIDL.forService)iin);
- }
- return new com.styleflying.AIDL.forService.Stub.Proxy(obj);
- }
- public android.os.IBinder asBinder()
- {
- return this;
- }
- @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
- {
- switch (code)
- {
- case INTERFACE_TRANSACTION:
- {
- reply.writeString(DESCRIPTOR);
- return true;
- }
- case TRANSACTION_registerTestCall:
- {
- data.enforceInterface(DESCRIPTOR);
- com.styleflying.AIDL.forActivity _arg0;
- _arg0 = com.styleflying.AIDL.forActivity.Stub.asInterface(data.readStrongBinder());
- this.registerTestCall(_arg0);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_invokCallBack:
- {
- data.enforceInterface(DESCRIPTOR);
- this.invokCallBack();
- reply.writeNoException();
- return true;
- }
- }
- return super.onTransact(code, data, reply, flags);
- }
- private static class Proxy implements com.styleflying.AIDL.forService
- {
- private android.os.IBinder mRemote;
- Proxy(android.os.IBinder remote)
- {
- mRemote = remote;
- }
- public android.os.IBinder asBinder()
- {
- return mRemote;
- }
- public java.lang.String getInterfaceDescriptor()
- {
- return DESCRIPTOR;
- }
- public void registerTestCall(com.styleflying.AIDL.forActivity cb) throws android.os.RemoteException
- {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeStrongBinder((((cb!=null))?(cb.asBinder()):(null)));
- mRemote.transact(Stub.TRANSACTION_registerTestCall, _data, _reply, 0);
- _reply.readException();
- }
- finally {
- _reply.recycle();
- _data.recycle();
- }
- }
- public void invokCallBack() throws android.os.RemoteException
- {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_invokCallBack, _data, _reply, 0);
- _reply.readException();
- }
- finally {
- _reply.recycle();
- _data.recycle();
- }
- }
- }
- static final int TRANSACTION_registerTestCall = (IBinder.FIRST_CALL_TRANSACTION + 0);
- static final int TRANSACTION_invokCallBack = (IBinder.FIRST_CALL_TRANSACTION + 1);
- }
- public void registerTestCall(com.styleflying.AIDL.forActivity cb) throws android.os.RemoteException;
- public void invokCallBack() throws android.os.RemoteException;
- }
我们能够看到在.java文件里都定义了一个抽象类Stub,Stub就是继承Binder。
好了,那我们那里用到了Binder呢?没错,就是Service,Service使用有两种方法,startService。bindeService。bindeService时在实现Service就必须实现 onBind 返回一个Binder对象,这个Binder对象就会被activity回调使用。
这样activity跟service就能够通信了。
当然是activity能够调用service了。
接下来的样例还实现了相互调用。
看mAIDLService.java:
- package com.styleflying.AIDL;
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- import android.os.RemoteCallbackList;
- import android.os.RemoteException;
- import android.util.Log;
- public class mAIDLService extends Service {
- private static final String TAG = "AIDLService";
- private forActivity callback;
- private void Log(String str) {
- Log.d(TAG, "------ " + str + "------");
- }
- @Override
- public void onCreate() {
- Log("service create");
- }
- @Override
- public void onStart(Intent intent, int startId) {
- Log("service start id=" + startId);
- }
- @Override
- public IBinder onBind(Intent t) {
- Log("service on bind");
- return mBinder;
- }
- @Override
- public void onDestroy() {
- Log("service on destroy");
- super.onDestroy();
- }
- @Override
- public boolean onUnbind(Intent intent) {
- Log("service on unbind");
- return super.onUnbind(intent);
- }
- public void onRebind(Intent intent) {
- Log("service on rebind");
- super.onRebind(intent);
- }
- private final forService.Stub mBinder = new forService.Stub() {
- @Override
- public void invokCallBack() throws RemoteException
- {
- callback.performAction();
- }
- @Override
- public void registerTestCall(forActivity cb) throws RemoteException
- {
- callback = cb;
- }
- };
- }
当中mBinder就是给activity调用了。然而这个类中的mBinder 中的registerTestCall传递的forActivity就是能service调用activity用的。
看mAIDLActivity.java:
- package com.styleflying.AIDL;
- import android.app.Activity;
- import android.content.ComponentName;
- import android.content.Context;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.os.RemoteException;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class mAIDLActivity extends Activity {
- private static final String TAG = "AIDLActivity";
- private Button btnOk;
- private Button btnCancel;
- private Button btnCallBack;
- private void Log(String str) {
- Log.d(TAG, "------ " + str + "------");
- }
- private forActivity mCallback = new forActivity.Stub() {
- public void performAction() throws RemoteException
- {
- Toast.makeText(mAIDLActivity.this, "this toast is called from service", 1).show();
- }
- };
- forService mService;
- private ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className,
- IBinder service) {
- mService = forService.Stub.asInterface(service);
- try {
- mService.registerTestCall(mCallback);}
- catch (RemoteException e) {
- }
- }
- public void onServiceDisconnected(ComponentName className) {
- Log("disconnect service");
- mService = null;
- }
- };
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- setContentView(R.layout.main);
- btnOk = (Button)findViewById(R.id.btn_ok);
- btnCancel = (Button)findViewById(R.id.btn_cancel);
- btnCallBack = (Button)findViewById(R.id.btn_callback);
- btnOk.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- Bundle args = new Bundle();
- Intent intent = new Intent(mAIDLActivity.this, mAIDLService.class);
- intent.putExtras(args);
- bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
- startService(intent);
- }
- });
- btnCancel.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- unbindService(mConnection);
- //stopService(intent);
- }
- });
- btnCallBack.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v)
- {
- try
- {
- mService.invokCallBack();
- } catch (RemoteException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- });
- }
- }
当中button点击bindeService时就会触发ServiceConnection,返回了mService = forService.Stub.asInterface(service); activity跟service实现了通信,再mService.registerTestCall(mCallback);} 这样service跟activity又能通信了。在mService.invokCallBack();顺序是activity->service->activity
还有几篇android多进程通信写得不错一并贴出来
http://www.cnblogs.com/BeyondAnyTime/p/3204119.html
http://www.apkbus.com/android-83462-1-1.html
http://blog.csdn.net/baodinglaolang/article/details/9903499
android 多进程 Binder AIDL Service的更多相关文章
- Android使用binder访问service的方式(一)
binder机制是贯穿整个android系统的进程间访问机制,经常被用来访问service,我们结合代码看一下binder在访问service的情形下是怎么具体使用的. service 你可以理解成没 ...
- Android 使用binder访问service的方式
binder机制是贯穿整个Android系统的进程间访问机制,经常被用来访问service,我们结合代码看一下binder在访问service的情形下是怎么具体使用的. service 你可以理解成没 ...
- Android中的跨进程通信方法实例及特点分析(一):AIDL Service
转载请注明出处:http://blog.csdn.net/bettarwang/article/details/40947481 近期有一个需求就是往程序中增加大数据的採集点,可是由于我们的Andro ...
- 跨进程调用Service(AIDL Service)
1.什么是aidl:aidl这是 Android Interface definition language的缩写,一看就明确.它是一种android内部进程通信接口的描写叙述语言.通过它我们能够定义 ...
- Android service binder aidl 关系
/********************************************************************************** * Android servic ...
- 图解Android - Binder 和 Service
在 Zygote启动过程 一文中我们说道,Zygote一生中最重要的一件事就是生下了 System Server 这个大儿子,System Server 担负着提供系统 Service的重任,在深入了 ...
- AIDL Service Android进程间通信机制
转载出处:http://www.apkbus.com/home.php?mod=space&do=blog&uid=664680&id=59465 我们知道,在Android ...
- Android 核心分析 之六 IPC框架分析 Binder,Service,Service manager
IPC框架分析 Binder,Service,Service manager 我首先从宏观的角度观察Binder,Service,Service Manager,并阐述各自的概念.从Linux的概念空 ...
- Android AIDL SERVICE 双向通信 详解
http://www.cnblogs.com/punkisnotdead/p/5062631.html 起因 是这个blog 提到了 用webview 的时候 用开启子进程的方式 可以极大避免内存泄露 ...
随机推荐
- java_日期和时间
1.System类中的currentTimeMillis:1970年1.1到现在的毫秒数 public class DateTest { public static void main(String[ ...
- css--css选择器,伪类
前戏 前面我们说过CSS规则由选择器和声明组成,我们要给标签设置属性,那我们就要找到对应的标签,CSS选择器可以帮我们找到我们需要的标签 css选择器有: 标签选择器 类选择器 ID选择器 全局选择器 ...
- Ubuntu 18的网络配置
包括Ubuntu 18.04和18.10,设置为静态IP及DNS. sudo vim /etc/netplan/50-cloud-init.yaml network: ethernets: enp4s ...
- python数组中数据位置交换 -- IndexError: list assignment index out of range
代码: t = [-10,-3,-100,-1000,-239,1] # 交换 -10和1的位置 t[5], t[t[5]-1] = t[t[5]-1], t[5] 报错: IndexError: l ...
- 文件默认权限umask掩码
umask命令 作用:用于显示.设置文件的缺省权限 格式:umask [-S] -S表示以rwx形式显示新建文件缺省权限 系统的默认掩码是0022 文件创建时的默认权限 = 0666 - umas ...
- Shell函数和正则表达式
1. shell函数 shell中允许将一组命令集合或语句形成一段可用代码,这些代码块称为shell函数.给这段代码起个名字称为函数名,后续可以直接调用该段代码. 格式: func() { #指定 ...
- 常见的linux命令及其翻译
常见的linux指令 1.ls ll 查看文件信息 2.cd 切换工作目录 cd 或 cd ~ 切换到/home/用户目录 cd. 切换到当前目录 cd.. 切换到上级目录 cd- 切换入上次所在的目 ...
- python:零散记录
1.rstrip()删除末尾指定字符串 例如:A = '1,2,3,4,5,' B = A.rstrip(',') B = '1,2,3,4,5' 2.isdigit()方法 Python isdig ...
- redis:哨兵集群配置
最少配置1主2从3哨兵 一.引言 上一篇文章我们详细的讲解了Redis的主从集群模式,其实这个集群模式配置很简单,只需要在Slave的节点上进行配置,Master主节点的配置不需要做任何更改,但是有一 ...
- 如何用 CSS 创作一个立体滑动 toggle 交互控件
效果预览 在线演示 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/pen/zjoOgX 可交互视频教程 此视 ...