之前记录了一个客户端如何跨进程地与一个服务端通信。如果只有一个客户端需要它,那么跨进程的意义也显得不那么大了。所以,我在此再建立了一个客端共同使用这个服务端。

  客户端的代码与之前的代码几乎一模一样。在此不贴代码了。唯一不同的是,文件结构不同。由于服务端写在之前的工程中,我们需要一套共同的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 ~

posted on 2016-03-29 23:57  Fishbonell  阅读(226)  评论(0编辑  收藏  举报