开发环境:windows7+eclipse+Android4.4
跳过本地服务,内容主要为跨进程与服务交互,交互方式为AIDL。程序结构分为服务端和客户端。
步骤1:
创建AIDL(android interface definition language)文件,文件要描述的是提供给客户端的接口
文件内容如下:
package com.example.aidl;
interface IRemoteService {
void action();
}
可以放到任意文件夹下,扩展名为aidl。
在eclipse环境下会自动在gen文件夹生成一个IRemote.java的文件,IRemote类实现了IRemoteService的方法并且继承自Binder,Binder是交互的桥梁,后续提供给客户端进行交互。
步骤2:
在服务端工程创建一个Service,示例代码如下:
package com.example.aidl;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.widget.Toast;
public class RemoteService extends Service {
private IRemoteService.Stub mBinder = new IRemoteService.Stub() {
@Override
public void action() throws RemoteException {
Toast.makeText(getApplicationContext(), "exec remote service action!", Toast.LENGTH_SHORT).show();
}
};
public void onCreate() {
super.onCreate();
};
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
代码包含了一个Stub成员,Stub的定义来自gen中新生成的IRemoteService.java。
在onBind中,service需要返回他自己的Binder,否则后续客户端无法使用。
步骤3:
修改服务端manifest文件,添加如下内容供客户端使用,为服务添加意图过滤器action:
<service android:name="com.example.aidl.RemoteService">
<intent-filter>
<action android:name="com.example.aidl.START_REMOTE_SERVICE"/>
</intent-filter>
</service>
步骤4:
在客户端的某个Activity类中添加启动服务的代码:
private IRemoteService mService;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "onServiceDisconnected");
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "onServiceConnected");
mService = IRemoteService.Stub.asInterface(service);
try {
mService.action();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
private void testService(){
// 模拟作为客户端绑定服务
Intent bindIntent = new Intent("com.example.aidl.START_REMOTE_SERVICE");
bindIntent.setPackage(getPackageName());
getApplicationContext().bindService(bindIntent, mConnection, Context.BIND_AUTO_CREATE);
}
注意:setPackage不可少,因为在lolipop版本后,必须显式声明调用者。