Android AIDL使用详解
2016-10-17 17:12
477 查看
在Android中, 每个应用程序都可以有自己的进程。在写UI应用的时候,经常要用到Service。在不同的进程中,怎样传递对象呢? 显然,Java中不允许跨进程内存共享,因此传递对象,只能把对象拆分成操作系统能理解的简单形式,以达到跨界对象访问的目的。在J2EE中,采用RMI的方式,可以通过序列化传递对象。在Android中,则采用AIDL的方式。理论上AIDL可以传递Bundle,但实际上做起来却比较麻烦.
Android跨进程通信方式具体做法就是在多个应用程序之间建立共同的服务机制,通过AIDL在不同应用程序之间达到数据共享和数据相互操作。
具体实现过程为:
1、创建AIDL 服务端。
1)创建.aidl文件,声明接口(IDvbService.aidl);
2、创建AIDL 客户端。
1)把之前编写的aidl文件(注意不是生成的java文件)和它的包目录拷贝到客户端的src目录中;
2)客户端调用服务端提供的服务接口(DvbServiceImpl.java);
4)调用该对象方法。
Android跨进程通信方式具体做法就是在多个应用程序之间建立共同的服务机制,通过AIDL在不同应用程序之间达到数据共享和数据相互操作。
具体实现过程为:
1、创建AIDL 服务端。
1)创建.aidl文件,声明接口(IDvbService.aidl);
package com.dvb.service; interface IDvbService { void startInitDvbModule(); int doSystemCmd(String cmd); int getCurstomerID(); boolean isFactorySW(); String getSerialNumber(); byte[] getFullSN(); String getEncryptSN(); void setPowerAction(int action); String[] getTimeZones(); int getCurZoneIndex(); void saveTimeZone(int index); Rect getOutRange(); void setOSDArea(int l, int t, int r, int b); int getHdmiIndex(); void setHdmiIndex(int index); }2)在Service中建个子类实现接口的存根(stub)对象,并在onBind()方法中返回该对象(DvbService.java);
package com.dvb.service; import android.app.Service; import android.content.Intent; import android.graphics.Rect; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import com.dvb.dbase.BOX_INFO_STRUCT; import com.dvb.dbase.dbaseManager; import com.dvb.fpanel.FpanelManager; import com.dvb.init.InitDVBModule; import com.dvb.init.InitDVBModule.InitStatus; import com.dvb.security.SecurityManager; import com.dvb.settingmodule.SettingManager; import com.dvb.specialcmd.SpecialCmd; import com.dvb.systemtime.SystemTimerService; public class DvbService extends Service { private String TAG = DvbService.class.getSimpleName(); private final IDvbService.Stub mBinder = new IDvbService.Stub() { @Override public void startInitDvbModule() throws RemoteException { InitStatus status = InitDVBModule.getInstance(getApplication()).getInitStatus(); if(status == InitStatus.UNINITIALIZED) InitDVBModule.getInstance(getApplication()).startInit(); } @Override public int doSystemCmd(String cmd) throws RemoteException { return SpecialCmd.getInstance(getApplication()).execSystemCmd(cmd); } @Override public int getCurstomerID() throws RemoteException { return InitDVBModule.getInstance(getApplication()).getInitBackMsg().iCustomID; } @Override public boolean isFactorySW() throws RemoteException { return InitDVBModule.getInstance(getApplication()).getInitBackMsg().iFactory_sw; } @Override public String getSerialNumber() throws RemoteException { return SecurityManager.getInstance(getApplication()).getSNNumber(); } @Override public byte[] getFullSN() throws RemoteException { return SecurityManager.getInstance(getApplication()).getSerialNumber(); } @Override public String getEncryptSN() throws RemoteException { return SecurityManager.getInstance(getApplication()).getEncryptSN().SNNumber; } @Override public void setPowerAction(int action) throws RemoteException { switch(action) { case 0: FpanelManager.getInstance(DvbService.this).setPowerReboot(); break; case 1: FpanelManager.getInstance(DvbService.this).setPowerStandby(); break; case 2: FpanelManager.getInstance(DvbService.this).setPowerShutUp(); break; } } @Override public String[] getTimeZones() throws RemoteException { if(SystemTimerService.getInstance(DvbService.this).getTimeZoneMaps() == null) { SystemTimerService.getInstance(DvbService.this).initTimeZoneList(); } return SystemTimerService.getInstance(DvbService.this).getTimeZoneNameArray(); } @Override public int getCurZoneIndex() throws RemoteException { return SystemTimerService.getInstance(DvbService.this).getZoneDefaultIndex(); } @Override public void saveTimeZone(int index) throws RemoteException { SystemTimerService.getInstance(DvbService.this).setTimeZone(index); SystemTimerService.getInstance(DvbService.this).saveZoneSelected(index); } @Override public Rect getOutRange() throws RemoteException { BOX_INFO_STRUCT boxInfo = dbaseManager.getInstance(getApplication()).getBoxInfo(); Rect rect = new Rect(boxInfo.screen_area_xpos, boxInfo.screen_area_ypos, boxInfo.screen_area_width, boxInfo.screen_area_height); return rect; } @Override public void setOSDArea(int l, int t, int r, int b) throws RemoteException { SettingManager.getInstance(getApplication()).setOSDArea(l, t, r, b); BOX_INFO_STRUCT boxInfo = dbaseManager.getInstance(getApplication()).getBoxInfo(); boxInfo.screen_area_xpos = l; boxInfo.screen_area_ypos = t; boxInfo.screen_area_width = r; boxInfo.screen_area_height = b; dbaseManager.getInstance(getApplication()).updateBoxInfo(boxInfo); } @Override public int getHdmiIndex() throws RemoteException { SettingManager settingManager = SettingManager.getInstance(getApplication()); BOX_INFO_STRUCT boxInfo = dbaseManager.getInstance(getApplication()).getBoxInfo(); return settingManager.getHDModeIndex(boxInfo.hdmi_mode); } @Override public void setHdmiIndex(int index) throws RemoteException { SettingManager settingManager = SettingManager.getInstance(getApplication()); BOX_INFO_STRUCT boxInfo = dbaseManager.getInstance(getApplication()).getBoxInfo(); int iHDValue = settingManager.getHDValueUnderSpecifiedTVSys(boxInfo.tv_type, index); settingManager.setHdmiMode(iHDValue); } }; public void onCreate() { super.onCreate(); InitStatus status = InitDVBModule.getInstance(getApplication()).getInitStatus(); if(status == InitStatus.UNINITIALIZED) InitDVBModule.getInstance(getApplication()).startInit(); }; @Override public IBinder onBind(Intent intent) { Log.d(TAG, "bind action "+intent.getAction()); if (IDvbService.class.getName().equals(intent.getAction())) { Log.d(TAG, "return mBinder"); return mBinder; } else { return null; } } }3)将Service添加进服务端或引用服务端的应用程序配置文件清单中(AndroidManifest.xml)。
<service android:name="com.dvb.service.DvbService" android:exported="true" android:process=":remote" > <intent-filter> <action android:name="com.dvb.service.IDvbService" /> </intent-filter> </service>
2、创建AIDL 客户端。
1)把之前编写的aidl文件(注意不是生成的java文件)和它的包目录拷贝到客户端的src目录中;
2)客户端调用服务端提供的服务接口(DvbServiceImpl.java);
package com.starview.tv.service; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.util.Log; import com.dvb.service.IDvbService; import com.starview.tv.util.LogTool; public class DvbServiceImpl { private static IDvbService instance; private static final Object obj = new Object(); private static ServiceConnection mRemoteConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { LogTool.d("benson", "ComponentName = " + className.getClassName()); instance = IDvbService.Stub.asInterface(service); synchronized (obj) { obj.notifyAll(); } } public void onServiceDisconnected(ComponentName className) { instance = null; } }; public static synchronized boolean isInit() { return instance != null; } public static synchronized boolean init(Context context) { if (instance == null) { Intent service = new Intent(IDvbService.class.getName()); boolean bBindOk = context.getApplicationContext().bindService(service, mRemoteConnection, Context.BIND_AUTO_CREATE); Log.d("benson", "bBindOk = " + bBindOk); return bBindOk; } return true; } public static synchronized boolean init(Context ctx, final InitListener listener) { if (instance == null) { if (listener != null) { new Thread() { @Override public void run() { synchronized (obj) { if (instance == null) { try { obj.wait(2000); } catch (InterruptedException e) { e.printStackTrace(); } } listener.onInitEnd(instance); } } }.start(); } Intent service = new Intent(IDvbService.class.getName()); try { boolean bBindOk = ctx.getApplicationContext().bindService(service, mRemoteConnection, Context.BIND_AUTO_CREATE); Log.d("benson", "bBindOk = " + bBindOk); return bBindOk; } catch (SecurityException e) { e.printStackTrace(); return false; } } else { if (listener != null) { listener.onInitEnd(instance); } return true; } } public static synchronized void deInit(Context context) { if (instance != null) { Log.i("benson", "deInit..."); context.unbindService(mRemoteConnection); instance = null; } } public static synchronized IDvbService getDvbService(final Context context) throws UnInitException { if (instance == null) { throw new UnInitException("Please Call init First"); } return instance; } public static class UnInitException extends Exception { private static final long serialVersionUID = 1L; public UnInitException() { super(); } public UnInitException(String detailMessage, Throwable throwable) { super(detailMessage, throwable); } public UnInitException(String detailMessage) { super(detailMessage); } public UnInitException(Throwable throwable) { super(throwable); } } public static interface InitListener { public void onInitEnd(IDvbService instance); } }3)在需要调用该服务的地方实例化该对象;
IDvbService dvbService = null; try { dvbService = DvbServiceImpl.getDvbService(mContext); } catch (UnInitException e) { e.printStackTrace(); return; }
4)调用该对象方法。
dvbService.setPowerAction(0);
相关文章推荐
- Android进阶:AIDL实现IPC使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解 +整合应用
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android中RemoteService的使用详解(Aidl、IPC机制)
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解
- Android AIDL使用详解 .
- Android AIDL使用详解
- android aidl 使用详解