Android 使用动态载入框架DL进行插件化开发

如有转载,请声明出处: 时之沙: http://blog.csdn.net/t12x3456    (来自时之沙的csdn博客)

概述:

随着应用的不断迭代。应用的体积不断增大,项目越来越臃肿,冗余添加.项目新功能的加入,无法确定与用户匹配性,发生严重异常往往牵一发而动全身,仅仅能紧急公布补丁版本号。强制用户进行更新.结果频繁的更新,反而容易减少用户使用黏性.或者是公司业务的不断发展,同系的应用越来越多,传统方式须要通过用户量最大的主项目进行引导下载并安装.

怎么办?

參考浏览器-插件开发模式:

一. 来能够将自己的应用分拆。某些功能能够在插件中实现,用到时再进行下载,并且不用安装.  假设有新功能的加入,不须要更新应用,仅仅要预留插件管理,我们就能够通过加入插件的方式。动态更新自己的应用,该功能须要改进或扩展,更新插件就可以,无需频繁安装或卸载(容易造成用户反感).

二. 相应同系应用,正常的引流方式仅仅能引导用户进行新应用的下载和安装,假设使用插件化开发,则无需安装应用,关闭插件功能也十分方便,省去应用安装和卸载的过程,能够实现无缝引流.

这里要向大家推荐一个开源的动态载入框架DL, 该项目由singwhatiwanna发起,眼下一共同拥有三个人开发。我有幸成为了当中的contributor.

假设你对DL动态载入框架还不熟悉。建议先看一下这篇文章:

APK动态载入框架DL解析http://blog.csdn.net/singwhatiwanna/article/details/39937639

假设你看过之后还会不太清晰,请看下DL插件化框架的全景图,例如以下

这里我主要向大家介绍一下利用DL框架进行开发的详细步骤:

1. 首先我们须要从github上获取项目代码:

https://github.com/singwhatiwanna/dynamic-load-apk

这里我们能够看到下载后的文件夹例如以下

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdDEyeDM0NTY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" />

lib文件夹就是我们的公共插件库

sample文件夹是相应的demo,  详细的project能够參照上面的DL全景图中的三种模式:

由于一般项目中。代码管理和开发团队相对独立,  一般插件project的团队是非常难接触主项目团队的代码.因此,这里主要以第一种,也是我们最为推荐的方式进行, 採用插件不依赖宿主的方式进行开发. 不须要两个团队过多的交互,开发效率相对较高.


2 导入libproject,例如以下所看到的:

能够看到bin文件夹下的dl-lib.jar, 假设我们须要对libproject进行改动。又一次build获取相应的dl-lib.jar就可以


3. 插件project的开发, 导入demo中的main-pluginproject

首先还是要强调插件开发的注意事项,以免出现不必要的错误

插件也须要引用DL的jar包。可是不能放入到插件project的libs文件夹以下,换句话说,就是插件编译的时候依赖jar包可是打包成apk的时候不要把jar包打进去,这是由于,dl-lib.jar已经在宿主project中存在了,假设插件中也有这个jar包,就会发生类链接错误。原因非常easy。内存中有两份一样的类。反复了。至于support-v4也是相同的道理。

对于eclipse非常easy。仅仅须要在插件project中创建一个文件夹。比方external-jars,然后把dl-lib.jar和support-v4.jar放进去。同一时候在.classpath中追加例如以下两句就可以:

<classpathentry kind="lib" path="external-jars/dl-lib.jar"/>
<classpathentry kind="lib" path="external-jars/android-support-v4.jar"/>

然后是插件开发中的详细步骤

 (1) 假设原有的为Activity,这里须要改为继承DLBasePluginActivity,假设原来为FragmentActivity,那么须要继承DLBasePluginFragmentActivity, for example:

public class MainActivity extends DLBasePluginActivity 
TestFragmentActivity extends DLBasePluginFragmentActivity

 (2) 假设须要插件独立安装执行, 仅仅要将jar放到libs以下就可以,若支持动态载入。仍需按上述注意事项加入 exteral-jars中

 (3)插件所须要权限须要在宿主project中声明

假设是实际开发,一般为从server获取插件,这里我们方便自己调试演示,将执行生成相应的插件apk,放入sd卡上的DynamicLoadHost文件夹中

4. 宿主project中将上述生成的dl-lib.jar加入libs就可以,例如以下所看到的为demo中提供的宿主project

在宿主project中,首先我们须要获取要调用的插件apk相应的MainActivity,DL的demo中插件路径为 sd卡上的DynamicLoadHost文件夹,没有的话须要创建。或者依据自己需求进行改动.

        String pluginFolder = Environment.getExternalStorageDirectory() + "/DynamicLoadHost";
        File file = new File(pluginFolder);
        File[] plugins = file.listFiles();
        if (plugins == null || plugins.length == 0) {
            mNoPluginTextView.setVisibility(View.VISIBLE);
            return;
        }

        for (File plugin : plugins) {
            PluginItem item = new PluginItem();
            item.pluginPath = plugin.getAbsolutePath();
            item.packageInfo = DLUtils.getPackageInfo(this, item.pluginPath);
            if (item.packageInfo.activities != null && item.packageInfo.activities.length > 0) {
                item.launcherActivityName = item.packageInfo.activities[0].name;
            }
            mPluginItems.add(item);
        }

接着是调起响应的apk,这时须要使用dl-lib.jar:

(1)通过Class.forName的方式获取我们须要调用的插件apk中MainActivity的class对象

  (2) 就上面提到的,我们须要推断该对象继承自DLBasePluginActivity还是DLBasePluginFragmentActivity,得到相应的代理class对象

  (3)使用相应的代理class对象调起插件apk

 PluginItem item = mPluginItems.get(position);
        Class<?

> proxyCls = null;

        try {
            Class<?

> cls = Class.forName(item.launcherActivityName, false,
                    DLClassLoader.getClassLoader(item.pluginPath, getApplicationContext(), getClassLoader()));
            if (cls.asSubclass(DLBasePluginActivity.class) != null) {
                proxyCls = DLProxyActivity.class;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            Toast.makeText(this,
                    "load plugin apk failed, load class " + item.launcherActivityName + " failed.",
                    Toast.LENGTH_SHORT).show();
        } catch (ClassCastException e) {
            // ignored
        } finally {
            if (proxyCls == null) {
                proxyCls = DLProxyFragmentActivity.class;
            }
            Intent intent = new Intent(this, proxyCls);
            intent.putExtra(DLConstants.EXTRA_DEX_PATH,
                    mPluginItems.get(position).pluginPath);
            startActivity(intent);
        }

最后执行宿主projectmain-host,就能够看到终于的效果:

相信大家经过如上步骤,能够对DL动态载入框架进行开发有了一定了解.眼下DL框架仍在不断扩展中。欢迎对我们的项目进行star,fork。或者提出宝贵的建议.,如有问题请及时反馈,我们会在兴许版本号中进行修复或者改进:

https://github.com/singwhatiwanna/dynamic-load-apk

时间: 2024-10-24 16:01:50

Android 使用动态载入框架DL进行插件化开发的相关文章

Android 使用动态加载框架DL进行插件化开发

如有转载,请声明出处: 时之沙: http://blog.csdn.net/t12x3456    (来自时之沙的csdn博客) 概述: 随着应用的不断迭代,应用的体积不断增大,项目越来越臃肿,冗余增加.项目新功能的添加,无法确定与用户匹配性,发生严重异常往往牵一发而动全身,只能紧急发布补丁版本,强制用户进行更新.结果频繁的更新,反而容易降低用户使用黏性.或者是公司业务的不断发展,同系的应用越来越多,传统方式需要通过用户量最大的主项目进行引导下载并安装. 怎么办?参考浏览器-插件开发模式: 一.

DL动态载入框架技术文档

DL动态载入框架技术文档 DL技术交流群:215680213 1. Android apk动态载入机制的研究 2. Android apk动态载入机制的研究(二):资源载入和activity生命周期管理 3. APK动态载入框架DL解析 4. Android 使用动态载入框架DL进行插件化开发 5. DL插件开发笔记 6. DL开发注意事项 附:DL层次结构图

Android组件化和插件化开发

http://www.cnblogs.com/android-blogs/p/5703355.html 什么是组件化和插件化? 组件化开发就是将一个app分成多个模块,每个模块都是一个组件(Module),开发的过程中我们可以让这些组件相互依赖或者单独调试部分组件等,但是最终发布的时候是将这些组件合并统一成一个apk,这就是组件化开发.插件化开发和组件化开发略有不用,插件化开发时将整个app拆分成很多模块,这些模块包括一个宿主和多个插件,每个模块都是一个apk(组件化的每个模块是个lib),最终

Android插件化开发,初入殿堂

好久没有写博客了,这次准备写写我这几天的研究成果--Android插件化开发框架CJFrameForAndroid. 好久没有写博客了,这次准备写写我这几天的研究成果--Android插件化开发框架CJFrameForAndroid. 背景交代 首先,你需要知道什么是插件化开发.就拿最常见的QQ来说,在第三个界面动态那里有个管理,点开后可以选择很多的增植功能,这里腾讯只放了一些网页应用,那么如果未来想加入一个打飞机游戏,要怎么做?让用户重新安装吗,这就是插件化开发所解决的问题. 用一句话来概括插

Android插件化开发---运行未安装apk中的Service

如果你还不知道什么叫插件化开发,那么你应该先读一读之前写的这篇博客:Android插件化开发,初入殿堂 上一篇博客主要从整体角度分析了一下Android插件化开发的几个难点与动态加载没有被安装的apk中的Activity和资源的方法.其实一般的插件开发主要也就是加载个Activity,读取一些资源图片之类的.但是总有遇到特殊情况的时候,比如加载Service. 要动态加载Service,有两种思路:一是通过NDK的形式,将Service通过C++运行起来(这种方法我没有尝试,只听群里的朋友说实现

详解Android插件化开发-资源访问

动态加载技术(也叫插件化技术),当项目越来越庞大的时候,我们通过插件化开发不仅可以减轻应用的内存和CPU占用,还可以实现热插拔,即在不发布新版本的情况下更新某些模块. 通常我们把安卓资源文件制作成插件的形式,无外乎有一下几种: zip.jar.dex.APK(未安装APK.安装APK) 对于用户来讲未安装的APK才是用户所需要的,不安装.不重启,无声无息的加载资源文件,这正是我们开发者追求的结果. 但是,开发中宿主程序调起未安装的插件apk,一个很大的问题就是资源如何访问,这些资源文件的ID都映

Android 插件化开发-主题皮肤更换

参考 http://www.2cto.com/kf/201501/366859.html 本项目是以插件化开发思想进行的,主要工作和代码如下 资源文件,这里以color资源为例 1.首先我们需要准备一个皮肤包,这个皮肤包里面不会包含任何Activity,里面只有资源文件,这里我为了简单,仅仅加入一个color.xml(其实就相当于Android系统中的framework_res.apk) <!--?xml version="1.0" encoding="utf-8&qu

Asp.Net MVC 插件化开发简化方案

Web 管理系统可以庞大到不可想像的地方,如果想就在一个 Asp.Net MVC 项目中完成开发,这个工程将会变得非常庞大,协作起来也会比较困难.为了解决这个问题,Asp.Net MVC 引入了 Areas 的概念,将模块划分到 Area 中去--然而 Area 仍然是主项目的一部分,多人协作的时候仍然很容易造成 .csproj 项目文件的冲突. 对于这类系统,比较好的解决办法是采用 SOA 的方式,把一个大的 Web 系统划分成若干微服务,通过一个含授权中心的 Web 集散框架组织起来.不过这

Android的Proxy/Delegate Application框架 (主要介绍插件化开发)

360技术团队地址:http://blogs.360.cn/blog/proxydelegate-application/ Android 插件开发,做成动态加载 美团Android DEX自动拆包及动态加载简介 实现一些特殊需求,如界面换肤.插件化等,我们希望改变应用的运行环境(surrounding).例如,我们希望某个应用在运行时,所有Class(包括自定义Application,下面假设它叫MyApplication)都被一个自定义的ClassLoader加载. 要实现这个需求,需要在M