AIDL实现跨APP通信(双向通信)

某天,接到了一人任务要在两个app互相传递一些消息,上网查了以后发现有几种方式。第一是广播、第二是AIDL,由于初出茅庐全不会就选择了AIDL。。。下面简单粗暴的开始贴代码好了。也是得到了网上的一些借鉴,若有雷同,嗯你懂的。


1.我们需要先建立AIDL文件。值得一提的是,我们要在main下建立一个专门用来放AIDL文件的包。非常重要!


其中,AIDLClient.aidl是客户端使用的接口,AIDLService是服务器所用的接口,Info是我们要传的自定义实体类。客户端就是想要主动给另一个app发送信息的一端,服务器就是接收信息并可以返回信息的一端。下面来看看最简单的AIDL里面该怎么写。

(1)AIDLClient.aidl

<pre style="font-family: 宋体; font-size: 9pt; background-color: rgb(255, 255, 255);"><pre name="code" class="java">// AIDLClient.aidl
package AIDL;

// Declare any non-default types here with import statements

interface AIDLClient {
    /**
     * 接收来自另一个app返回的信息
     */
     void receiveByServer(String message);
}



(2)AIDLClient.aidl

package AIDL;

// Declare any non-default types here with import statements
import AIDL.AIDLClient;
import AIDL.AIDLService;

interface AIDLService {
    /**
     * 接收来自客户端发来的信息
     * @param info 实体类
     */
    Info getServerdanceInfo(in Info info);
}

在客户端给服务器发送请求后,服务器会返回一个Info类型的实体。

(3)Info.aidl

// Info.aidl
package AIDL;

parcelable Info;

在Info中我们要使用我们自己写的实体类类型,而不是用基本类型。

(4)Info

public class Info implements Parcelable {
    private String message;
我们实体类中其实只有一个String类型,当然也可以有多个自己设置的类型,但是一定要使用AIDL中支持的几个基本类型。剩下的就自动生成出get/set等就可以了,记得多写一个默认构造函数。

2.在客户端app中我们要实现点击按钮,发送消息并将服务器返回的消息显示着Textview中。

<pre name="code" class="java">public class MainActivity extends AppCompatActivity {

    public static final String TAG = "MainActivity";
    private static final String BIND_ACTION = "AIDL.service";
    private Button button;
    private TextView textView;
    private AIDLService aidlServce;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }

    private void init(){
        button = (Button)findViewById(R.id.sendAIDL);
        textView = (TextView)findViewById(R.id.receive);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //绑定服务
                getServiceConnect();
            }
        });
    }

    private void getServiceConnect(){
        Intent it = new Intent();
        it.setAction(BIND_ACTION);
        it.setPackage("com.example.zjl.aidlservice_demo");
        startService(it);
        bindService(it, serviceConnection,BIND_AUTO_CREATE);
    }

    ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG,"onServiceDisconnected");

        }
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG,"onServiceConnected");
            //获取服务端传过来的IBinder对象,通过该对象调用服务端的方法
            aidlServce = AIDLService.Stub.asInterface(service);
            if (aidlServce != null){
                handlerInfo();
            }
        }

    };

    private void handlerInfo(){
        Info mInfo = new Info();
        mInfo.setMessage("肿么可以次兔兔");

        try {
            Info serverInfo = new Info();
            //调用服务端的方法
            serverInfo = aidlServce.getServerInfo(mInfo,mClient);
            unbindService(serviceConnection);
        }catch (RemoteException e){
            e.printStackTrace();
        }
    }

    AIDLClient.Stub mClient = new AIDLClient.Stub()
    {
        //客户端回调方法的具体实现
        @Override
        public void receiveByServer(String param) throws RemoteException {
            textView.setText(param);
        }
    };
}




这里需要注意的是,在用Intent绑定服务的时候在5.0以后需要对package进行设定,否则会报错。setPackage里的参数为服务器端的包名。XML就俩控件,一个button一个Textview就不写了。


3.在服务器中需要把AIDL连同包一起复制到main下同客户端一样。build后会自动生成java文件,否则使用不了。





4.在服务端写一个service用于接收来自客户端的请求。

public class service extends Service {
    public static final String TAG = "DanceAIDLService";
    private AIDLClient aidlClient;
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
    /**
     * 创建服务
     */
    @Override
    public void onCreate()
    {
        super.onCreate();
    }

    /**
     * 销毁服务
     */
    @Override
    public void onDestroy()
    {
        super.onDestroy();
    }

    /**
     * 启动服务
     */
    @Override
    public void onStart(Intent intent, int startId)
    {
        super.onStart(intent, startId);
    }

    /**
     * 解绑服务
     */
    @Override
    public boolean onUnbind(Intent intent)
    {
        aidlClient = null;
        return super.onUnbind(intent);
    }

    //处理来自客户端的消息

    AIDLService.Stub mBinder = new AIDLService.Stub() {

        @Override
        public Info getServerInfo(Info info, AIDLClient client) throws RemoteException {

            aidlClient = client;
            aidlClient.receiveByServer("收到来自客户端的消息:"+info.getMessage());
            Log.d(TAG,info.getMessage()+"       ");

            Info newInfo = new Info();
            newInfo.setMessage(info.getMessage());

            return newInfo;

        }
    };
}

我们这把从客户端发过来的信息加了几个字又返了回去。并且配置service。

<service
            android:name=".service"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="AIDL.service"></action>
            </intent-filter>
</service>

5.最后,还需要在build.gradle中添加用于区分aidl和java的命令。卸载Android括号内就可以。

 sourceSets{
        main{
            java.srcDirs = ['src/main/java', 'src/main/aidl']
        }
    }

怎么样是不是好简单,但是AIDL那些文件真的很容易出错误哦,所以在第一次写的时候可能会总也调不好,有点耐心慢慢调吧~~




展开阅读全文

没有更多推荐了,返回首页