实现步骤
1.建立一个aidl文件,在里面定义好接口,注意里面不能写public修饰符,同接口一样,包名要一致.
package com.systemset.aidl; interface ILight { int getScreenBrightness(); void setScreenBrightness(int value); int getScreenOffTimeout(); void setScreenOffTimeout(int value); }
2.实现服务端进程,提供对应的功能.
Build生成对应的java文件(自动生成的java文件在/gen/yourPackage中),里面包含了一个内部类Stub,写一个Service子类,并在内部继承Stub类,实现对应的功能.
// ILight.java
package com.systemset.aidl; public interface ILight extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.systemset.aidl.ILight { private static final java.lang.String DESCRIPTOR = "com.systemset.aidl.ILight"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.systemset.aidl.ILight interface, * generating a proxy if needed. */ public static com.systemset.aidl.ILight asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof com.systemset.aidl.ILight))) { return ((com.systemset.aidl.ILight)iin); } return new com.systemset.aidl.ILight.Stub.Proxy(obj); } @Override public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_getScreenBrightness: { data.enforceInterface(DESCRIPTOR); int _result = this.getScreenBrightness(); reply.writeNoException(); reply.writeInt(_result); return true; } case TRANSACTION_setScreenBrightness: { data.enforceInterface(DESCRIPTOR); int _arg0; _arg0 = data.readInt(); this.setScreenBrightness(_arg0); reply.writeNoException(); return true; } case TRANSACTION_getScreenOffTimeout: { data.enforceInterface(DESCRIPTOR); int _result = this.getScreenOffTimeout(); reply.writeNoException(); reply.writeInt(_result); return true; } case TRANSACTION_setScreenOffTimeout: { data.enforceInterface(DESCRIPTOR); int _arg0; _arg0 = data.readInt(); this.setScreenOffTimeout(_arg0); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements com.systemset.aidl.ILight { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } @Override public int getScreenBrightness() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getScreenBrightness, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; } @Override public void setScreenBrightness(int value) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(value); mRemote.transact(Stub.TRANSACTION_setScreenBrightness, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public int getScreenOffTimeout() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getScreenOffTimeout, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; } @Override public void setScreenOffTimeout(int value) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(value); mRemote.transact(Stub.TRANSACTION_setScreenOffTimeout, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_getScreenBrightness = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_setScreenBrightness = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); static final int TRANSACTION_getScreenOffTimeout = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2); static final int TRANSACTION_setScreenOffTimeout = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3); } public int getScreenBrightness() throws android.os.RemoteException; public void setScreenBrightness(int value) throws android.os.RemoteException; public int getScreenOffTimeout() throws android.os.RemoteException; public void setScreenOffTimeout(int value) throws android.os.RemoteException; }
// LightService.java
package com.systemset.aidl; import static android.util.Log.d; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import com.apical.systemset.util.SetManager; public class LightService extends Service { private static final String TAG = "debug"; private LightServer mLightServer; public LightService() { } @Override public IBinder onBind(Intent intent) { if (mLightServer == null) mLightServer = new LightServer(); d(TAG, "LightService: onBind"); return mLightServer; } @Override public boolean onUnbind(Intent intent) { d(TAG, "LightService: onUnbind"); mLightServer = null; return super.onUnbind(intent); } public class LightServer extends ILight.Stub { @Override public int getScreenBrightness() throws RemoteException { int value = SetManager.getInstance().getScreenBrightness( LightService.this); d(TAG, "LightServer: call getScreenBrightness! return value is " + value); return value; } @Override public void setScreenBrightness(int value) throws RemoteException { d(TAG, "LightServer: call setScreenBrightness.value is " + value); SetManager.getInstance().setScreenBrightness(LightService.this, value); } @Override public int getScreenOffTimeout() throws RemoteException { int value = SetManager.getInstance().getScreenOffTimeout( LightService.this); d(TAG, "LightServer: call getScreenOffTimeout! return value is " + value); return value; } @Override public void setScreenOffTimeout(int value) throws RemoteException { d(TAG, "LightServer: call setScreenOffTimeout.value is " + value); SetManager.getInstance().setScreenOffTimeout(LightService.this, value); } } public static int getScreenBrightness(Context context) { int light = 0; try { light = Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS); } catch (SettingNotFoundException e) { d(TAG, "SystemManager:", e); } return light; } public static void setScreenBrightness(Context context, int value) { Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, value); } public static int getScreenOffTimeout(Context context) { int time = 0; try { time = Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT); } catch (SettingNotFoundException e) { d(TAG, "SystemManager:", e); } return time; } public static void setScreenOffTimeout(Context context, int value) { Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, value); } }
// 在AndroidManifest.xml中注册服务
<service android:name="com.systemset.aidl.LightService" android:process=":remote" android:exported="true" > <intent-filter> <action android:name="com.apical.systemset.aidl.LightService" /> </intent-filter> </service>
3.实现客户端进程,提供对应的功能.
将aidl文件拷贝到客户端进程中,注意包名需要一致.同样Build之后,会生成对应的java文件.使用bindService启动服务,在ServiceConnection的
onServiceConnected函数中使用Stub.asInterface(binder)取得对象.
Intent intent = new Intent();
intent.setAction("com.apical.systemset.aidl.LightService");
// 不能调用setPackage,否则会出现如下错误
// Unable to start service Intent { act=com.apical.systemset.aidl.LightService pkg=com.diysoul.aidlclient } U=0: not found
// intent.setPackage(getPackageName());
boolean bindResult = bindService(intent, mServiceConnection,
Context.BIND_AUTO_CREATE);
// ServiceConnection对象定义如下
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName componentName) {
d(TAG, "ServiceConnection componentName:" + componentName);
mLight = null;
}
@Override
public void onServiceConnected(ComponentName componentName,
IBinder binder) {
d(TAG, "ServiceConnection componentName:" + componentName);
mLight = ILight.Stub.asInterface(binder);
try {
int screenBrightness = mLight.getScreenBrightness();
int ScreenOffTimeout = mLight.getScreenOffTimeout();
d(TAG, "client getScreenBrightness = " + screenBrightness);
d(TAG, "client getScreenOffTimeout = " + ScreenOffTimeout);
} catch (RemoteException e) {
d(TAG, "", e);
}
}
};
// MainActivity.java
package com.diysoul.aidlclient; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import static android.util.Log.d; import com.systemset.aidl.ILight; public class MainActivity extends Activity { private static final String TAG = "debug"; private ILight mLight; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(); intent.setAction("com.apical.systemset.aidl.LightService"); // Unable to start service Intent { act=com.apical.systemset.aidl.LightService pkg=com.diysoul.aidlclient } U=0: not found // intent.setPackage(getPackageName()); boolean bindResult = bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); d(TAG, "bindResult:" + bindResult); d(TAG, "mLight:" + mLight); } @Override protected void onDestroy() { super.onDestroy(); unbindService(mServiceConnection); } private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName componentName) { d(TAG, "ServiceConnection componentName:" + componentName); mLight = null; } @Override public void onServiceConnected(ComponentName componentName, IBinder binder) { d(TAG, "ServiceConnection componentName:" + componentName); mLight = ILight.Stub.asInterface(binder); try { int screenBrightness = mLight.getScreenBrightness(); int ScreenOffTimeout = mLight.getScreenOffTimeout(); d(TAG, "client getScreenBrightness = " + screenBrightness); d(TAG, "client getScreenOffTimeout = " + ScreenOffTimeout); } catch (RemoteException e) { d(TAG, "", e); } } }; }