Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用
2016-12-29 15:56
776 查看
在上一篇文章Android IPC机制(二)用Messenger进行进程间通信中我们介绍了使用Messenger来进行进程间通信的方法,但是我们能发现Messenger是以串行的方式来处理客户端发来的信息,如果有大量的消息发到服务端,服务端仍然一个一个的处理再响应客户端显然是不合适的。另外,Messenger用来进程间进行数据传递但是却不能满足跨进程的方法调用,接下来我们来使用AIDL来实现跨进程方法调用,此前我们都是用Eclipse来实现的,这次我们看看在Android Studio中使用AIDL有什么不同。
1. 创建AIDL文件
我们将项目的目录结构调为Android模式,在Java同级目录创建aidl文件夹,在文件夹中创建一个包名和应用包名一致的包
我们先创建一个IGameManager.aidl的文件,这里面有两个方法分别是addGame和getGameList。(IGameManager.aidl)
2
3
4
5
6
1
2
3
4
5
6
在AIDL文件中支持的数据类型包括:
基本数据类型
String和CharSequence
List:只支持ArrayList,里面的元素都必须被AIDL支持
Map:只支持HashMap,里面的元素必须被AIDL 支持
实现Parcelable接口的对象
所有AIDL接口
在IGameManager.aidl中我们用到了Game这个类,这个类实现了Parcelable,在AIDL 文件中我们要import 进来,来看看Game类。(Game.java)
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
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
在这里不去讲怎么去实现Parcelable 接口,在上面的IGameManager.aidl文件中我们用到了Game这个类,所以我们也要创建Game.aidl,来申明Game实现了parcelable 接口。(Game.aidl)
2
1
2
这个时候我们重新编译程序,工程就会自动生成IGameManager.aidl对应的接口文件,这个文件生成的位置和Eclipse的位置不同,我们将项目的目录结构调整为project模式,在app–>build–>generated–>soure–>aidl–>debug目录下我们找到自己的包名文件,在文件中有一个接口文件IGameManager。
IGameManager接口文件的代码这里就不说了,有兴趣的可以下载本项目的源码去了解下。
2. 创建服务端
服务端我们在onCreate方法中创建了两个游戏的信息并创建Binder对象实现了AIDL的接口文件中的方法,并在onBind方法中将Binder对象返回。(AIDLService.java)
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
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
当然我们不要忘了这个服务端应该运行在另一个进程,在AndroidManifest.xml文件中配置service:
1
3. 客户端调用
最后我们在客户端onCreate方法中调用bindService方法绑定远程服务端,绑定成功后将返回的Binder对象转换为AIDL接口,这样我们就可以通过这个接口来调用远程服务端的方法了。(AIDLActivity.java)
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
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
绑定成功后我们创建了一个新的Game然后调用远程服务端的addGame方法将新游戏添加进去,然后调用循环将远端服务中的所有的游戏在打印出来,我们运行程序
打印出了远程服务端的所有的游戏,这样我们就成功的在客户端通过AIDL来调用远程服务端的方法了。
github源码下载
1. 创建AIDL文件
我们将项目的目录结构调为Android模式,在Java同级目录创建aidl文件夹,在文件夹中创建一个包名和应用包名一致的包
我们先创建一个IGameManager.aidl的文件,这里面有两个方法分别是addGame和getGameList。(IGameManager.aidl)
package com.example.liuwangshu.moonaidl; import com.example.liuwangshu.moonaidl.Game; interface IGameManager { List<Game>getGameList(); void addGame(in Game game); }1
2
3
4
5
6
1
2
3
4
5
6
在AIDL文件中支持的数据类型包括:
基本数据类型
String和CharSequence
List:只支持ArrayList,里面的元素都必须被AIDL支持
Map:只支持HashMap,里面的元素必须被AIDL 支持
实现Parcelable接口的对象
所有AIDL接口
在IGameManager.aidl中我们用到了Game这个类,这个类实现了Parcelable,在AIDL 文件中我们要import 进来,来看看Game类。(Game.java)
package com.example.liuwangshu.moonaidl; import android.os.Parcel; import android.os.Parcelable; public class Game implements Parcelable { public String gameName; public String gameDescribe; public Game(String gameName,String gameDescribe){ this.gameName=gameName; this.gameDescribe=gameDescribe; } protected Game(Parcel in) { gameName=in.readString(); gameDescribe=in.readString(); } public static final Creator<Game> CREATOR = new Creator<Game>() { @Override public Game createFromParcel(Parcel in) { return new Game(in); } @Override public Game[] newArray(int size) { return new Game[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(gameName); dest.writeString(gameDescribe); } }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
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
在这里不去讲怎么去实现Parcelable 接口,在上面的IGameManager.aidl文件中我们用到了Game这个类,所以我们也要创建Game.aidl,来申明Game实现了parcelable 接口。(Game.aidl)
package com.example.liuwangshu.moonaidl; parcelable Game;1
2
1
2
这个时候我们重新编译程序,工程就会自动生成IGameManager.aidl对应的接口文件,这个文件生成的位置和Eclipse的位置不同,我们将项目的目录结构调整为project模式,在app–>build–>generated–>soure–>aidl–>debug目录下我们找到自己的包名文件,在文件中有一个接口文件IGameManager。
IGameManager接口文件的代码这里就不说了,有兴趣的可以下载本项目的源码去了解下。
2. 创建服务端
服务端我们在onCreate方法中创建了两个游戏的信息并创建Binder对象实现了AIDL的接口文件中的方法,并在onBind方法中将Binder对象返回。(AIDLService.java)
package com.example.liuwangshu.moonaidl; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class AIDLService extends Service{ private CopyOnWriteArrayList<Game> mGameList=new CopyOnWriteArrayList<Game>(); private Binder mBinder= new IGameManager.Stub() { @Override public List<Game> getGameList() throws RemoteException { return mGameList; } @Override public void addGame(Game game) throws RemoteException { mGameList.add(game); } }; @Override public void onCreate() { super.onCreate(); mGameList.add(new Game("九阴真经ol", "最好玩的武侠网游")); mGameList.add(new Game("大航海时代ol","最好玩的航海网游")); } @Override public IBinder onBind(Intent intent) { return mBinder; } }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
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
当然我们不要忘了这个服务端应该运行在另一个进程,在AndroidManifest.xml文件中配置service:
<service android:name=".AIDLService" android:process=":remote"></service>1
1
3. 客户端调用
最后我们在客户端onCreate方法中调用bindService方法绑定远程服务端,绑定成功后将返回的Binder对象转换为AIDL接口,这样我们就可以通过这个接口来调用远程服务端的方法了。(AIDLActivity.java)
package com.example.liuwangshu.moonaidl; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import java.util.List; public class AIDLActivity extends AppCompatActivity { private final static String TAG="AIDLActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_aidl); Intent mIntent=new Intent(AIDLActivity.this,AIDLService.class); bindService(mIntent,mServiceConnection, Context.BIND_AUTO_CREATE); } private ServiceConnection mServiceConnection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { IGameManager iGameManager=IGameManager.Stub.asInterface(service); Game game=new Game("月影传说","最好玩的武侠单机游戏"); try { iGameManager.addGame(game); List<Game> mList=iGameManager.getGameList(); for(int i=0;i<mList.size();i++){ Game mGame=mList.get(i); Log.i(TAG,mGame.gameName+"---"+mGame.gameDescribe); } } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onDestroy() { super.onDestroy(); unbindService(mServiceConnection); } }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
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
绑定成功后我们创建了一个新的Game然后调用远程服务端的addGame方法将新游戏添加进去,然后调用循环将远端服务中的所有的游戏在打印出来,我们运行程序
打印出了远程服务端的所有的游戏,这样我们就成功的在客户端通过AIDL来调用远程服务端的方法了。
github源码下载
相关文章推荐
- Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用
- Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用
- Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用
- Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用
- AIDL/IPC Android AIDL/IPC 进程通信机制——超具体解说及使用方法案例剖析(播放器)
- Android-->IPC(跨进程)通信Aidl的实现方法
- Android IPC机制(三)——利用AIDL实现跨进程通信
- 示例:Android使用AIDL实现跨进程通讯(IPC)
- Android应用程序四大组件之使用AIDL如何实现跨进程调用Service
- Android Binder机制实现进程间数据交换(不使用aidl实现)
- 在Android使用AIDL实现IPC机制
- 【Android开发艺术探索】IPC机制(四)-使用AIDL进行跨进程通信
- android使用AIDL实现跨进程通讯(IPC)
- Android IPC机制(二):AIDL的基本使用方法
- Android应用程序四大组件之使用AIDL如何实现跨进程调用Service
- Android四大组件应用系列5——使用AIDL实现跨进程调用Service
- android使用AIDL实现跨进程通讯(IPC)
- 使用AIDL实现IPC通信之——简单调用远程服务的方法
- Android---44---使用AIDL Service 实现跨进程调用Service
- Androidk开发入门之使用AIDL实现进程通信