Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用

1. 创建AIDL文件

我们将项目的目录结构调为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 {
     List<Game>getGameList();
      void addGame(in Game game);
}

在AIDL文件中支持的数据类型包括:

  • 基本数据类型
  • String和CharSequence
  • List:只支持ArrayList,里面的元素都必须被AIDL支持
  • Map:只支持HashMap,里面的元素必须被AIDL 支持
  • 实现Parcelable接口的对象
  • 所有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 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);
    }
}

在这里不去讲怎么去实现Parcelable 接口,在上面的IGameManager.aidl文件中我们用到了Game这个类,所以我们也要创建Game.aidl,来申明Game实现了parcelable 接口。(Game.aidl)

package  com.ywl5320.jnithread;
parcelable Game;

 

这个时候我们重新编译程序,工程就会自动生成IGameManager.aidl对应的接口文件

2. 创建服务端

服务端我们在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 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();
        Log.i("chenzhu","先在这一个进程中添加两个数据");
        mGameList.add(new Game("九阴真经ol", "最好玩的武侠网游"));
        mGameList.add(new Game("大航海时代ol","最好玩的航海网游"));

    }
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

 

当然我们不要忘了这个服务端应该运行在另一个进程,在AndroidManifest.xml文件中配置service:

<service
    android:process=":secondprocess"
    android:name=".MyService"
    android:enabled="true"
    android:exported="true"></service>

3. 客户端调用

最后我们在客户端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);
                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);

    }

}

绑定成功后我们创建了一个新的Game然后调用远程服务端的addGame方法将新游戏添加进去,然后调用循环将远端服务中的所有的游戏在打印出来,我们运行程序

参考链接:http://liuwangshu.cn/application/ipc/3-aidl.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值