之前记录了一个客户端如何跨进程地与一个服务端通信。如果只有一个客户端需要它,那么跨进程的意义也显得不那么大了。所以,我在此再建立了一个客端共同使用这个服务端。
客户端的代码与之前的代码几乎一模一样。在此不贴代码了。唯一不同的是,文件结构不同。由于服务端写在之前的工程中,我们需要一套共同的aidl接口,和Book.java。不仅代码相同,包名也要完全相同。所以,建议直接从服务端的那里复制文件。
这样,我们即可以保证这个客户端与服务端正常通信。
说到这里,我不免产生了疑问。我的这个服务端是否太公开了。任何一个客户端,不管是不是我的客户端,只要造出这个接口和包结构,然后知道我Service的Action都可以与我通信。这不科学!
经查阅,比较通用的有两种方式,对这一通信进行权限管理。
我们着重记录其中一种,即onBind验证。
首先,我们在服务端的AndroidManifest里面进行配置。
<permission android:name="com.dream.fishbonelsy.aidldemo.permission.ACCESS" android:protectionLevel="normal"/>
这个配置即是设定一个口令,口令可以自定。
这里值得注意的是,服务端的process必须设为remote,不能设为任意进程名。一旦设为任意进程名,这里就不受权限的控制了。
<service android:name=".service.BookManagerService" android:process=":remote" > <intent-filter> <action android:name="com.dream.fishbonelsy.aidldemo.service"/> </intent-filter> </service>
完成了配置,我们再来修改服务端的少量代码。
@Override public IBinder onBind(Intent intent) { int check = checkCallingOrSelfPermission("com.dream.fishbonelsy.aidldemo.permission.ACCESS"); if (check == PackageManager.PERMISSION_DENIED){ return null; } return mBinder; }
将Service中的onBind方法,修改成这样,在返回IBinder之前,做一次判断。如果没有权限则返回空。
无论哪个客户端,想要与这个服务端通信时,只需要在自己的AndroidManifest中加上
<uses-permission android:name="com.dream.fishbonelsy.aidldemo.permission.ACCESS"/>
即可。
这样,一个基本的跨进程,C/S模型算是完成了。但是还有很多坑在其中,下回再探究。
Done ~