我们将项目的目录结构调为Android模式,在java同级目录创建aidl文件夹,在文件夹中创建一个包名和应用包名一致的包
我们先创建一个IGameManager.aidl的文件,这里面有两个方法分别是addGame和getGameList。(IGameManager.aidl)
// IGameManager.aidl package com.ywl5320.jnithread; import com.ywl5320.jnithread.Game; // Declare any non-default types here with import statements interface IGameManager { ListgetGameList(); void addGame(in Game game); }
在AIDL文件中支持的数据类型包括:
在IGameManager.aidl中我们用到了Game这个类,这个类实现了Parcelable,在AIDL 文件中我们要import 进来,来看看Game类。(Game.java)
package com.ywl5320.jnithread; import android.annotation.SuppressLint; import android.os.Parcel; import android.os.Parcelable; @SuppressLint("ParcelCreator") 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 CreatorCREATOR = new Creator () { @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); } }
在这里不去讲怎么去实现Parcelable 接口,在上面的IGameManager.aidl文件中我们用到了Game这个类,所以我们也要创建Game.aidl,来申明Game实现了parcelable 接口。(Game.aidl)
package com.ywl5320.jnithread; parcelable Game; |
这个时候我们重新编译程序,工程就会自动生成IGameManager.aidl对应的接口文件
服务端我们在onCreate方法中创建了两个游戏的信息并创建Binder对象实现了AIDL的接口文件中的方法,并在onBind方法中将Binder对象返回。(MyService.java)
package com.ywl5320.jnithread; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import static android.content.ContentValues.TAG; public class MyService extends Service { public MyService() { } private CopyOnWriteArrayListmGameList=new CopyOnWriteArrayList (); private Binder mBinder= new IGameManager.Stub() { @Override public List getGameList() throws RemoteException { return mGameList; } @Override public void addGame(Game game) throws RemoteException { mGameList.add(game); } }; @Override public void onCreate() { super.onCreate(); Log.i("chenzhu","先在这一个进程中添加两个数据"); mGameList.add(new Game("九阴真经ol", "最好玩的武侠网游")); mGameList.add(new Game("大航海时代ol","最好玩的航海网游")); } @Override public IBinder onBind(Intent intent) { return mBinder; } }
当然我们不要忘了这个服务端应该运行在另一个进程,在AndroidManifest.xml文件中配置service:
最后我们在客户端onCreate方法中调用bindService方法绑定远程服务端,绑定成功后将返回的Binder对象转换为AIDL接口,这样我们就可以通过这个接口来调用远程服务端的方法了。
package com.ywl5320.jnithread; 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 android.view.View; import android.widget.TextView; import java.util.List; public class MainActivity extends AppCompatActivity { String TAG ="chenzhu"; private ThreadDemo threadDemo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //这两种启动方式可以去看看有啥不同 // Intent myServiceIntent=new Intent(MainActivity.this,MyService.class); // this.startService(myServiceIntent); Intent mIntent=new Intent(MainActivity.this,MyService.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); ListmList=iGameManager.getGameList(); for(int i=0;i 绑定成功后我们创建了一个新的Game然后调用远程服务端的addGame方法将新游戏添加进去,然后调用循环将远端服务中的所有的游戏在打印出来,我们运行程序
参考链接:http://liuwangshu.cn/application/ipc/3-aidl.html