再议模块化设计

再议模块化设计

前言

    先前的文档有提及过2种针对****安装包过大的功能剥离和拆分的方案:以前(1)把需要剥离的功能逻辑使用jar报读方式剥离,并通过DexClassloader方式来加载;(2) 使用SL4A的方式来实现;现在例外介绍一种,按照界面和功能来拆分****.然后把这个功能创建成一个apk,通过sharedUserId的方式将子功能apk和主程序联系在一起,并且运行在同一个进程中,资源等共享.

1.  sharedUserId

android下,默认的情况是,每个apk相互独立的,基本上每个应用都是一个dalvik虚拟机,都有一个uid,如果多个apk共用一个uid,就可以作为一个独立应用的集成,运行在一个单独的dalvik虚拟机.配置代码如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:sharedUserId="com.nd.android.pandareader"

    package="com.nd.android.pandareader" android:versionCode="2600" android:versionName="2.6">

...

</manifest>

    那这样子就需要在****加载的是否把相同配置的apk检索出来,并加载到应用中.如下代码:

//遍历包名,来获取插件

PackageManager pm=getPackageManager();

 

List<PackageInfo> pkgs=pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);

for(PackageInfo pkg : pkgs){

//包名

    String packageName=pkg.packageName;

    String sharedUserId= pkg.sharedUserId;

    //sharedUserId是开发时约定好的,这样判断是否为自己人 if(!"com.android".equals(sharedUserId)||"com.android".equals(packageName)){

       //相同sharedUserIdapk

       ...

    }

}

主程序还可以通过侦听packgeManager的安装完成广播,在****的运行期来动态的加载新更新的插件apk包。

这种方式插件apk包被设计成<category android:name="android.intent.category.DEFAULT" />所以不会在桌面的应用程序列表中显现,但是会系统的已下载应用列表中显示,所以这样子,在拆分构功能的时候就需要一些技巧,比如把能够独自成一个应用的功能拆分出来,例如文件列表,wifi传送等.一方面也为机子提供这样的应用,另一方面为****做技术支撑.

在拆分功能之后,还需要就规定这些功能模块的描述,以使得主程序能够找到这些功能模块,并且在这些的模块中抽象出接口,以便方便的调用.因为属于同一个进程,所以在主程序中很方便的利用下面的代码来创建功能模块的上下文,通过描述性文件和抽象的接口就能直接运行功能模块(测试中直接用invoke来调用).

try{

    Context pkgContext=createPackageContext(pkg.packageName,

       Context.CONTEXT_INCLUDE_CODE|Context.CONTEXT_IGNORE_SECURITY);

    Class clazz=pkgContext.getClassLoader().loadClass("com.android.uid_1.UidSun1Activity");

    Activity activity=(Activity)clazz.newInstance();

    Method m=clazz.getMethod("setText", String.class);

    m.invoke(activity, "****子程序调用测试用例");

}catch(Exception e){

}

你可能感兴趣的:(模块化设计)