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

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

34资源网2022-07-16368

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

通俗易懂来讲就是,拆成多个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组件化,插件化内容请搜索萬仟网以前的文章或继续浏览下面的相关文章希望大家以后多多支持萬仟网!

看完文章,还可以扫描下面的二维码下载快手极速版领4元红包

快手极速版二维码

快手极速版新人见面礼

除了扫码领红包之外,大家还可以在快手极速版做签到,看视频,做任务,参与抽奖,邀请好友赚钱)。

邀请两个好友奖最高196元,如下图所示:

快手极速版邀请好友奖励

扫描二维码推送至手机访问。

版权声明:本文由34楼发布,如需转载请注明出处。

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

分享给朋友:

相关文章

koko卡卡拖地机器人家用全自动擦地机推荐

koko卡卡拖地机器人家用全自动擦地机推荐

koko卡卡智能拖地机是东莞市宝联电子科技有限公司旗下产品,隶属于香港概念数码科技有限公司,其主要研发机器人吸尘器等高科技领域家居产品,想知道卡卡智能拖地机好用吗,看看下面是网友使用koko卡卡智能拖地机的相关介绍,希望对大家有所帮助。1、…

疫情还是很严峻,最近去超市都要检测了

疫情还是很严峻,最近去超市都要检测了

疫情还是很严峻,最近去超市也要各种检测了,记得前不久我去超市还是比较宽松的,基本上没有专门的检测员,口罩也不用戴。最近可能是外省一些地区疫情比较严重了,所以温州这边现在检测也更加严格了,我最近去超市买东西都要各种检测,买个菜呀,买些零食吃的…

电脑微信可以发多大的视频(视频超过40分钟发送步骤)

电脑微信可以发多大的视频(视频超过40分钟发送步骤)

虽然腾讯在短视频领域迟迟未能取得优势,微视也很难撼动抖音、快手等头部APP的地位,但一直以来都未放弃这块蛋糕。 2021年二季度,随着微信以及Wechat活跃用户账户达到12.5亿,微信视频号的成长空间也被进一步拉大。而腾讯也很可能在短视频…

一周涨粉几百万,“张同学”凭什么火?

一周涨粉几百万,“张同学”凭什么火?

编者按:本文来自微信公众号时趣研究院(ID:SocialTouch2020),作者:时有趣,创业邦经授权转载 在最近的一段时间里,名叫“张同学”的博主刷屏了抖音,相关话题频频登上热榜,甚至还得到了人民网的点评。 张同学第一个视频的发布日期…

融资丨「PPIO边缘云」完成亿元A1轮融资,刷新边缘云领域融资记录

融资丨「PPIO边缘云」完成亿元A1轮融资,刷新边缘云领域融资记录

创业邦获悉,近日,边缘云公司PPIO宣布完成过亿元A1轮融资,由创世伙伴、张江科投、磐霖资本等多家机构联合投资,Pre-A轮投资方蓝驰创投、沸点资本及华业天成继续追加投资,光源资本担任融资财务顾问。这是公司半年内再次获投资人支持,公司A2轮…

微信开放外链,社交想象力有限

微信开放外链,社交想象力有限

编者按:本文来自新熵,创业邦经授权发布,封面图来自摄图网。 作者|古廿 编辑|伊页 网易云音乐上市,丁磊在现场讲了很多的未来,比如元宇宙。但未来是摸不着看不见的,所以愿意放眼未来的人,多半还要立足脚下。 脚下的立足往往来自两个方面:一…