Android AIDL IPC机制

更好的设计Android软件应该熟悉掌握AIDL IPC机制,可以让你编写的组件类似Windows ActiveX COM一样更好的复用,提供类似像Symbian那样的服务器机制。服务可以很好的解决在后台运行无UI的窗口。我们创建一个aidl文件名为 android123.aidl下面是示例代码,修改于Android SDK文档。
标签:  Android SDK  AIDL

代码片段(4)[全屏查看所有代码]

1. [代码]一、创建AIDL文件     

?
1
2
3
4
5
6
7
8
9
10
11
12
ackage cn.com.android123;
 
引入声明
import cn.com.android123.IAtmService;
 
// 声明一个接口,这里演示的是银行ATM程序
interface IBankAccountService {
     int getAccountBalance(); //返回整数,无参数
     void setOwnerNames(in List<String> names); //不返回,包含一个传入List参数
     BankAccount createAccount(in String name, int startingDeposit, in IAtmService atmService); //返回一个自定义类型
     int getCustomerList(in String branch, out String[] customerList); //返回整形,输入一个分支,输出一个客户列表
}

2. [代码]二、实现一个接口     

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//显示的提供一个导出接口,为客户端提供绑定。
 
public class RemoteService extends Service {
     @Override
     public IBinder onBind(Intent intent) {
         if (IRemoteService. class .getName().equals(intent.getAction())) {
             return mBinder;
         }
         if (ISecondary. class .getName().equals(intent.getAction())) {
             return mSecondaryBinder;
         }
         return null ;
     }
 
  //第一个接口
 
     private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
         public void registerCallback(IRemoteServiceCallback cb) {
             if (cb != null ) mCallbacks.register(cb);
         }
         public void unregisterCallback(IRemoteServiceCallback cb) {
             if (cb != null ) mCallbacks.unregister(cb);
         }
     };
 
//第二个接口
 
     private final ISecondary.Stub mSecondaryBinder = new ISecondary.Stub() {
         public int getPid() {
             return Process.myPid();
         }
         public void basicTypes( int anInt, long aLong, boolean aBoolean,
                 float aFloat, double aDouble, String aString) {
         }
     };
 
}

3. [代码]三、客户端交互     

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
通过Android.os提供的Parcelable类型来传递数据,通常我们使用Eclipse+ADT插件来完成,在Eclipse中在Package Explorer view视图上单击鼠标右键,选择Create Aidl preprocess file for Parcelable classes(创建aidl预编译文件),最终我们创建一个名为android123.aidl文件
*/
 
import android.os.Parcel;
import android.os.Parcelable;
 
public final class Rect implements Parcelable {
public int left;
public int top;
public int right;
public int bottom;
 
public static final Parcelable.Creator<Rect> CREATOR = new Parcelable.Creator<Rect>() {
public Rect createFromParcel(Parcel in) {
return new Rect(in);
}
 
public Rect[] newArray( int size) {
return new Rect[size];
}
};
 
public Rect() {
}
 
private Rect(Parcel in) {
readFromParcel(in);
}
 
public void writeToParcel(Parcel out) { //当前数据写入到Parcel中
out.writeInt(left);
out.writeInt(top);
out.writeInt(right);
out.writeInt(bottom);
}
 
public void readFromParcel(Parcel in) { //从Parcel中读取数据
left = in.readInt();
top = in.readInt();
right = in.readInt();
bottom = in.readInt();
}
}

4. [代码]IPC调用方式     

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
public class RemoteServiceBinding extends Activity {
     /** The primary interface we will be calling on the service. */
     IRemoteService mService = null ;
     /** Another interface we use on the service. */
     ISecondary mSecondaryService = null ;
 
     Button mKillButton;
     TextView mCallbackText;
 
     private boolean mIsBound;
 
     /**
      * Standard initialization of this activity.  Set up the UI, then wait
      * for the user to poke it before doing anything.
      */
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
 
         setContentView(R.layout.remote_service_binding);
 
         // Watch for button clicks.
         Button button = (Button)findViewById(R.id.bind);
         button.setOnClickListener(mBindListener);
         button = (Button)findViewById(R.id.unbind);
         button.setOnClickListener(mUnbindListener);
         mKillButton = (Button)findViewById(R.id.kill);
         mKillButton.setOnClickListener(mKillListener);
         mKillButton.setEnabled( false );
 
         mCallbackText = (TextView)findViewById(R.id.callback);
         mCallbackText.setText( "Not attached." );
     }
 
     /**
      * Class for interacting with the main interface of the service.
      */
     private ServiceConnection mConnection = new ServiceConnection() {
         public void onServiceConnected(ComponentName className,
                 IBinder service) {
             // This is called when the connection with the service has been
             // established, giving us the service object we can use to
             // interact with the service.  We are communicating with our
             // service through an IDL interface, so get a client-side
             // representation of that from the raw service object.
             mService = IRemoteService.Stub.asInterface(service);
             mKillButton.setEnabled( true );
             mCallbackText.setText( "Attached." );
 
             // We want to monitor the service for as long as we are
             // connected to it.
             try {
                 mService.registerCallback(mCallback);
             } catch (RemoteException e) {
                 // In this case the service has crashed before we could even
                 // do anything with it; we can count on soon being
                 // disconnected (and then reconnected if it can be restarted)
                 // so there is no need to do anything here.
             }
 
             // As part of the sample, tell the user what happened.
             Toast.makeText(RemoteServiceBinding. this , R.string.remote_service_connected,
                     Toast.LENGTH_SHORT).show();
         }
 
         public void onServiceDisconnected(ComponentName className) {
             // This is called when the connection with the service has been
             // unexpectedly disconnected -- that is, its process crashed.
             mService = null ;
             mKillButton.setEnabled( false );
             mCallbackText.setText( "Disconnected." );
 
             // As part of the sample, tell the user what happened.
             Toast.makeText(RemoteServiceBinding. this , R.string.remote_service_disconnected,
                     Toast.LENGTH_SHORT).show();
         }
     };
 
     /**
      * Class for interacting with the secondary interface of the service.
      */
     private ServiceConnection mSecondaryConnection = new ServiceConnection() {
         public void onServiceConnected(ComponentName className,
                 IBinder service) {
             // Connecting to a secondary interface is the same as any
             // other interface.
             mSecondaryService = ISecondary.Stub.asInterface(service);
             mKillButton.setEnabled( true );
         }
 
         public void onServiceDisconnected(ComponentName className) {
             mSecondaryService = null ;
             mKillButton.setEnabled( false );
         }
     };
 
     private OnClickListener mBindListener = new OnClickListener() {
         public void onClick(View v) {
             // Establish a couple connections with the service, binding
             // by interface names.  This allows other applications to be
             // installed that replace the remote service by implementing
             // the same interface.
             bindService( new Intent(IRemoteService. class .getName()),
                     mConnection, Context.BIND_AUTO_CREATE);
             bindService( new Intent(ISecondary. class .getName()),
                     mSecondaryConnection, Context.BIND_AUTO_CREATE);
             mIsBound = true ;
             mCallbackText.setText( "Binding." );
         }
     };
 
     private OnClickListener mUnbindListener = new OnClickListener() {
         public void onClick(View v) {
             if (mIsBound) {
                 // If we have received the service, and hence registered with
                 // it, then now is the time to unregister.
                 if (mService != null ) {
                     try {
                         mService.unregisterCallback(mCallback);
                     } catch (RemoteException e) {
                         // There is nothing special we need to do if the service
                         // has crashed.
                     }
                 }
 
                 // Detach our existing connection.
                 unbindService(mConnection);
                 unbindService(mSecondaryConnection);
                 mKillButton.setEnabled( false );
                 mIsBound = false ;
                 mCallbackText.setText( "Unbinding." );
             }
         }
     };
 
     private OnClickListener mKillListener = new OnClickListener() {
         public void onClick(View v) {
             // To kill the process hosting our service, we need to know its
             // PID.  Conveniently our service has a call that will return
             // to us that information.
             if (mSecondaryService != null ) {
                 try {
                     int pid = mSecondaryService.getPid();
                     // Note that, though this API allows us to request to
                     // kill any process based on its PID, the kernel will
                     // still impose standard restrictions on which PIDs you
                     // are actually able to kill.  Typically this means only
                     // the process running your application and any additional
                     // processes created by that app as shown here; packages
                     // sharing a common UID will also be able to kill each
                     // other's processes.
                     Process.killProcess(pid);
                     mCallbackText.setText( "Killed service process." );
                 } catch (RemoteException ex) {
                     // Recover gracefully from the process hosting the
                     // server dying.
                     // Just for purposes of the sample, put up a notification.
                     Toast.makeText(RemoteServiceBinding. this ,
                             R.string.remote_call_failed,
                             Toast.LENGTH_SHORT).show();
                 }
             }
         }
     };
 
     // ----------------------------------------------------------------------
     // Code showing how to deal with callbacks.
     // ----------------------------------------------------------------------
 
     /**
      * This implementation is used to receive callbacks from the remote
      * service.
      */
     private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() {
         /**
          * This is called by the remote service regularly to tell us about
          * new values.  Note that IPC calls are dispatched through a thread
          * pool running in each process, so the code executing here will
          * NOT be running in our main thread like most other things -- so,
          * to update the UI, we need to use a Handler to hop over there.
          */
         public void valueChanged( int value) {
             mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0 ));
         }
     };
 
     private static final int BUMP_MSG = 1 ;
 
     private Handler mHandler = new Handler() {
         @Override public void handleMessage(Message msg) {
             switch (msg.what) {
                 case BUMP_MSG:
                     mCallbackText.setText( "Received from service: " + msg.arg1);
                     break ;
                 default :
                     super .handleMessage(msg);
             }
         }
 
     };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
Android IPC(Inter-Process Communication)机制是指在Android系统中,不同进程之间进行通信的方式。Android中的应用程序通常都运行在自己的进程中,如果不同应用程序之间需要进行通信,或者同一个应用程序的不同进程之间需要进行通信,就需要使用IPC机制Android系统提供了多种IPC机制,包括: 1. Intent:Intent是一种轻量级的IPC方式,可以用来实现不同应用程序之间的通信。通过发送Intent,可以启动其他应用程序的Activity或Service,或者在不同应用程序之间传递数据。 2. Binder:Binder是一种基于进程间通信(IPC)的机制,它是Android系统中进程间通信的基础。通过Binder,可以在不同的进程之间传递对象、调用远程方法等。 3. ContentProvider:ContentProvider是Android中一种特殊的组件,用于在不同的应用程序之间共享数据。通过ContentProvider,可以将数据存储在一个应用程序中,然后在其他应用程序中访问这些数据。 4. Messenger:Messenger是一种轻量级的IPC方式,它基于Binder实现。通过Messenger,可以在不同进程之间传递Message对象。 5. AIDLAndroid Interface Definition Language):AIDL是一种专门用于Android的IDL语言,它可以定义跨进程通信(IPC)接口。通过AIDL,可以在不同进程之间传递复杂的数据结构。 6. Socket:Socket是一种基于网络的IPC方式,可以在不同的设备之间进行通信。通过Socket,可以在不同的进程或设备之间传递数据。 以上是Android中常用的IPC机制,不同的IPC机制适用于不同的场景。开发者需要根据具体的需求选择合适的IPC机制

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值