今天复习了下AIDL,做下整理。
概念:
AIDL (Android Interface Definition Language), Android接口定义语言,Android提供的IPC (Inter Process Communication,进程间通信)的一种独特实现。
注意点:
客户点写Intent时,格式最好是:(ComponentName(要找的Service的包名,要找到Service的全类名))
Intent intent=new Intent();
intent.setComponent(new ComponentName("com.hrx.kaka.aidltest","com.hrx.kaka.aidltest.MyService"));
因为在5.0之前可以使用Action找到跨进程的类,5.0之后不行(异常:java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=service })。
省略之前创建“anotherapp”项目的过程。。
省略要提供服务的“app”项目创建一个Service的过程。。。。
最终目的:使得anotherapp启动app的MyService,并进行通讯。
第一步:在“app”项目中创建一个aidl文件。
自动生成一个aidl文件,并写两个接口,一个用于接收数据,一个用于发送数据。
然后重构下项目
第二布:
在MyService里的onBind()方法中返回实现的Aidl方法。(具体啥方法可以在adil文件里定义)
第三布:
在”anotherapp”中绑定MyService。
public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {
Intent intent;
private IAppServiceBinder binder =null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent();
intent.setComponent(new ComponentName("com.hrx.kaka.aidltest", "com.hrx.kaka.aidltest.MyService"));
initView();
}
private void initView() {
findViewById(R.id.start_service).setOnClickListener(this);
findViewById(R.id.stop_service).setOnClickListener(this);
findViewById(R.id.bind_service).setOnClickListener(this);
findViewById(R.id.unbind_service).setOnClickListener(this);
findViewById(R.id.sync_service).setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.start_service:
startService(intent);
break;
case R.id.stop_service:
stopService(intent);
break;
case R.id.bind_service:
bindService(intent, this, Context.BIND_AUTO_CREATE);
break;
case R.id.unbind_service:
unbindService(this);
break;
case R.id.sync_service://传输数据到app
if (binder!=null){
try {
binder.setData("我传过来了");
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
}
}
//绑定的时候调用
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
System.out.println("bind service");
binder=IAppServiceBinder.Stub.asInterface(iBinder);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
}
第四步:
在要进行通讯的anotherapp项目也用同样的方法新建aidl,注意包名要与app项目的相同,然后直接把aidl文件复制进去。
第五步:
编写anotherapp调用aidl接口的代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {
Intent intent;
private IAppServiceBinder binder =null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent();
intent.setComponent(new ComponentName("com.hrx.kaka.aidltest", "com.hrx.kaka.aidltest.MyService"));
initView();
}
private void initView() {
findViewById(R.id.start_service).setOnClickListener(this);
findViewById(R.id.stop_service).setOnClickListener(this);
findViewById(R.id.bind_service).setOnClickListener(this);
findViewById(R.id.unbind_service).setOnClickListener(this);
findViewById(R.id.sync_service).setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.start_service:
startService(intent);
break;
case R.id.stop_service:
stopService(intent);
break;
case R.id.bind_service:
bindService(intent, this, Context.BIND_AUTO_CREATE);
break;
case R.id.unbind_service:
unbindService(this);
break;
case R.id.sync_service://传输数据到app
if (binder!=null){
try {
binder.getFromAnotherApp("我传过来了");
} catch (RemoteException e) {
e.printStackTrace();
}
try {
System.out.println(binder.returnToFromAnotherApp());
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
}
}
//绑定的时候调用
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
System.out.println("bind service");
binder=IAppServiceBinder.Stub.asInterface(iBinder);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
}
仅仅只是对AIDL这块的使用做下记录。
刚刚看到网上有人讨论绑定Service解绑后不会停止的问题做下记录:
通过bindService启动的Service在unbindService后会停止。
通过startService启动再bindService进行绑定的Service不会停止,一定要调用stopService才会停止。