当前位置:首页 > 谈天说地

Android组件化、插件化详细讲解

34资源网2022-07-16444

什么是组件化(通俗易懂)

通俗易懂来讲就是,拆成多个module开发就是组件化。

app的部分功能模块在打包时并不以传统⽅式打包进apk⽂件中,⽽是以另⼀种形式⼆次封装进apk内部,或者放在⽹络上适时下载,在需要的时候动态对这些功能模块进⾏加载,称之为插件化。这些单独⼆次封装的功能模块apk,就称作插件,初始安装的apk称作宿主。插件化是组件化的更进⼀步推进。

插件化基础之反射:

反射的写法

    try {
            class utilclass = class.forname("com.hencoder.demo.hidden.util");
            constructor utilconstructor = utilclass.getdeclaredconstructors()[0];
            utilconstructor.setaccessible(true);
            object util = utilconstructor.newinstance();
            method shoutmethod = utilclass.getdeclaredmethod("shout");
            shoutmethod.setaccessible(true);
            shoutmethod.invoke(util);
        } catch (classnotfoundexception e) {
            e.printstacktrace();
        } catch (nosuchmethodexception e) {
            e.printstacktrace();
        } catch (illegalaccessexception e) {
            e.printstacktrace();
        } catch (instantiationexception e) {
            e.printstacktrace();
        } catch (invocationtargetexception e) {
            e.printstacktrace();
        }

反射的⽬的

java既然提供了可⻅性关键字public、private等等,⽤来限制代码之间的可⻅性,为什么⼜要提供反射功能?可⻅性特性的⽀持不是为了代码不被坏⼈使⽤,⽽是为了程序开发的简洁性。安全性的话,可⻅性的⽀持提供的是safety 的安全,⽽不是security的安全。即,可⻅性的⽀持让程序更不容易写出bug,⽽不是更不容易被⼈⼊侵。反射的⽀持可以让开发者在可⻅性的例外场景中,可以突破可⻅性限制来调⽤⾃⼰需要的api。这是基于对开发者在使⽤反射时已经⾜够了解和谨慎的假设的。所以,可⻅性的⽀持不是为了防御外来者⼊侵,因此反射功能的⽀持并没有什么不合理。

关于dex:

  • class:java编译后的⽂件,每个类对应⼀个class⽂件
  • dex:dalvik executable把class打包在⼀起,⼀个dex可以包含多个class⽂件
  • odex:optimized dex针对系统的优化,例如某个⽅法的调⽤指令,会把虚拟的调⽤转换为使⽤具体的index,这样在执⾏的时候就不⽤再查找了
  • oat:optimized androidfile type。使⽤aot策略对dex预先编译(解释)成本地指令,这样再运⾏阶段就不需再经历⼀次解释过程,程序的运⾏可以更快
  • aot:ahead-of-time compilation预先编译

插件化原理:动态加载

通过⾃定义classloader来加载新的dex⽂件,从⽽让程序员原本没有的类可以被使⽤,这就是插件化的原理。

例如:把utils拆到单独的项⽬,打包apk作为插件引⼊:

 file f = new file(getcachedir() + "/demo-debug.apk");
        if (!f.exists()) {
            try { 
                inputstream is = getassets().open("apk/demo-debug.apk");
                int size = is.available();
                byte[] buffer = new byte[size];
                is.read(buffer);
                is.close();
                fileoutputstream fos = new fileoutputstream(f);
                fos.write(buffer);
                fos.close();
            } catch (exception e) {
                throw new runtimeexception(e);
            }
        }
    dexclassloader classloader = new dexclassloader(f.getpath(),
    getcodecachedir().getpath(), null, null);
      try {
            class oldclass = classloader.loadclass("com.hencoder.demo.hidden.util");
            constructor utilconstructor = oldclass.getdeclaredconstructors()[0];
            utilconstructor.setaccessible(true);
            object util = utilconstructor.newinstance();
            method shoutmethod = oldclass.getdeclaredmethod("shout");
            shoutmethod.setaccessible(true);
            shoutmethod.invoke(util);
            class activityclass = classloader.loadclass("com.hencoder.demo.mainactivity");
            startactivity(new intent(this, activityclass));
        } catch (classnotfoundexception e) {
            e.printstacktrace();
        } catch (nosuchmethodexception e) {
            e.printstacktrace();
        } catch (illegalaccessexception e) {
            e.printstacktrace();
        } catch (instantiationexception e) {
            e.printstacktrace();
        } catch (invocationtargetexception e) {
            e.printstacktrace();
        }

问题⼀:未注册的组件(例如activity)不能打开

  • 解决⽅式⼀:代理activity
  • 解决⽅式⼆:欺骗系统
  • 解决⽅式三:重写gradle打包过程,合并androimanifest.xml

问题⼆:资源⽂件⽆法加载

解决⽅式:⾃定义assetmanager和resources对象

   private assetmanager createassetmanager (string dexpath) {
        try {
            assetmanager assetmanager = assetmanager.class.newinstance();
            method addassetpath = assetmanager.getclass().getmethod("addassetpath", string.class);
            addassetpath.invoke(assetmanager, dexpath);
            return assetmanager;
        } catch (exception e) {
            e.printstacktrace();
            return null;
        }
    }
private resources createresources(assetmanager assetmanager) {
        resources superres = mcontext.getresources();
        resources resources = new resources(assetmanager, superres.getdisplaymetrics(), superres.getconfiguration());
        return resources;
    }

插件化有什么用?

  • 早期:解决dex 65535问题。⾕歌后来也出了multidex⼯具来专⻔解决
  • 懒加载来减少软件启动速度:有可能,实质上未必会快
  • 减⼩安装包⼤⼩:可以
  • 项⽬结构拆分,依赖完全隔离,⽅便多团队开发和测试,解决了组件化耦合度太⾼的问题:这个使⽤模块化就够了,况且模块化解耦不够的话,插件化也解决不了这个问题
  • 动态部署:可以
  • 热修复:可以

到此这篇关于android组件化、插件化详细讲解的文章就介绍到这了,更多相关android组件化,插件化内容请搜索萬仟网以前的文章或继续浏览下面的相关文章希望大家以后多多支持萬仟网!

版权声明:34楼发布

本文链接:https://www.34l.com/post/19280.html

分享给朋友:

相关文章

女人奋斗励志语录分享10句

女人奋斗励志语录分享10句

1、即便无人喝彩,也要守住自己的人生。每一次失败,都是成功的伏笔;每一次考验,都有一份收获;每一次泪水,都有一次醒悟;每一次磨难,都有生命的财富。每一次伤痛,都是成长的支柱。…

曹德旺的经典语录分享

曹德旺的经典语录分享

曹德旺,福耀玻璃集团创始人、董事长。中国反倾销胜诉第一人、中国首善、安永企业家奖首位华人获得者 。福耀玻璃目前是中国第一、世界第二大汽车玻璃供应商。他是不行贿的企业家,自称“没送过一盒月饼”,以人格做事;他是行善的佛教徒,从1983年第一次…

应用汇下载安装最新版(2021最新版应用汇app)

应用汇下载安装最新版(2021最新版应用汇app)

Donews8月17日消息(记者 邱慧)近日,为安卓手机服务的应用型软件“应用汇”新版正式上线,同时推出“应用收藏”功能——“应用集”。 应用集主要分为“推荐”、“最热”、“最新”三类。应用汇官方介绍,此次新版上线后,安装包被优化缩小,给…

虚拟内存太低怎么设置(电脑磁盘空间不足清理步骤)

虚拟内存太低怎么设置(电脑磁盘空间不足清理步骤)

在电脑的平时使用中,经常会出现内存不足的提示,有时可能小伙伴们会疑惑了,明明自己是16G内存的性能为何也能出现这种提示呢?这是当你在运行多个大程序的时候,对内存的需求非常大,当物理内存不能满足需求时,有可能导致程序关闭而数据保存错误。那么在…

知识直播出圈:张朝阳的物理课里 藏着直播的另一种答案

知识直播出圈:张朝阳的物理课里 藏着直播的另一种答案

编者按:本文转自熊出墨请注意,作者彬彬,创业邦经授权转载。 大家都知道,声和光在不同的条件下传播速度会发生变化。但有没有想过,知识、信息的传播也是如此。 1970年,美国传播学者蒂奇纳等人的研究小组提出了知识鸿沟的理论假设:社会经济地位高的…

首页页眉怎么去掉横线(教你三招快速处理)

首页页眉怎么去掉横线(教你三招快速处理)

Word可以说是office里算简单的了,不管是谁都能比较好的使用Word,但是要用好Word也不是那么容易的。所以今天介绍的这几个Word小技巧也是十分实用的,快来学起来吧! 字符加圈圈 一 很多时候,我们在编号的时候总会用到这个带圈字…