1.android 系统中,各应用程序都在自己的进程中运行,进程之间一般无法直接交换数据,为了实现这种跨进程通信(interprocess communication 简称IPC),android 提供了AIDL Service。今天这篇博客主要讲下ipc,基本数据的交互。下一篇在讲复杂性数据的交互。
2.第一步:需要创建一个AIDL文件。 首先创建一个project,然后在创建一个AIDL文件。如下图
这个文件是一个接口,不过和java接口不同,这个接口里面的抽象方法不能用public修饰。其他的地方和接口差不多。
在这个接口中我声明了俩个抽象方法,如下图:
// IMyAidlInterface.aidl
package com.example.lenovo.aidltest;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
//Aidl接口和java接口不同,方法不能用public接口生命;
String getcolor();
double getweight();
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
}
刚学习ipc的时候,可能找不到这个文件在哪,很多文章说在aidl文件夹下可以找到 ,但是楼主却没找到。最后发现在
找到了这个抽象类接口。怎样做的呢。就是得到Aidl文件之后,先make-project下 然后再上面图片中的路径下寻找。
第二步: 在创建一个service类,并在里面实现了 这个java接口(在这里我做实验的时候接口是IMyAidlInterface.Stub
抽象类)。具体如下图:
package com.example.lenovo.aidltest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class MyService extends Service {
IpcTest test;
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
test=new IpcTest();
}
@Override
public IBinder onBind(Intent intent) {
return test;
}
class IpcTest extends IMyAidlInterface.Stub{
@Override
public String getcolor() throws RemoteException {
return "黑色";
}
@Override
public double getweight() throws RemoteException {
return 88.45;
}
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
}
}
为了方面起见,在重写的方法getcolor,和getweight中,我是直接返回数据的。
然后再AndroidManifest 文件中声明这个Service ,并加上Intent-Filter 设置好action。
第三步:创建新的project,这个项目就是调用Service的项目。之后把含有Aidl文件的project的目录 ,也就是
这个文件都要拷贝到新建的项目中。注意要完全一模一样。包括里面的package,我做的时候,虽然你是直接copy到新项目中的,但是as会自动把你的这个package名称改掉。于是报错了。
第四步:在MainActivity里面直接调用这个Service。具体详细代码如下:
package com.example.lenovo.ipcclient;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.example.lenovo.aidltest.IMyAidlInterface;
public class MainActivity extends AppCompatActivity {
IMyAidlInterface test;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
test= IMyAidlInterface.Stub.asInterface(service);
try {
String s=test.getcolor();
Toast.makeText(MainActivity.this,s,Toast.LENGTH_LONG).show();
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button but= (Button) findViewById(R.id.but);
TextView color= (TextView) findViewById(R.id.color);
TextView weight= (TextView) findViewById(R.id.weight);
but.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent();
intent.setAction("android.intent.action.ipc");
//this is important
intent.setPackage("com.example.lenovo.aidltest");
bindService(intent, conn, Service.BIND_AUTO_CREATE);
}
});
final Button unbind= (Button) findViewById(R.id.unbind);
unbind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unbindService(conn);
}
});
}
}
ServiceConnection con 这个地方需要主要,asInterface(service)这个静态方法拿到,那个抽象类的。这个方法可以在 java接口中看到。拿到了那个对象,就可以直接调用getcolor方法了。
好了调用简单数据类型的 IPC,就到这里了,大家可以试试瞧,有什么不懂的,可以留言。