当前位置:首页 > 谈天说地 > 正文内容

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

34资源网2022年07月16日 10:32294

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

通俗易懂来讲就是,拆成多个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

分享给朋友:

相关文章

情浓时,海誓山盟;情淡时,形同陌路

情浓时,海誓山盟;情淡时,形同陌路

1、如果一个人影响到了你的情绪,你的焦点应该放在控制自己的情绪上,而不是影响你情绪的人身上。只有这样,才能真正自信起来。2、重要的不是你从哪里来,而是你到哪里去,找准方向,继续努力。3、所有的节日都不是为了礼物,而是提醒大家别忘了爱与被爱。...

分享二十句毕业告别的经典语录

分享二十句毕业告别的经典语录

1、曾经拼命想逃离的世界,却又在往后的日子里,念念不忘。2、今天毕业了,再也不能逃课了。3、人生何处不相逢。4、昨日的青空 随少年挥手消失在人海之中。5、时间是让人猝不及防的东西。6、开始于xxxx年初秋,结束于xxxx年盛夏。7、我的生命...

30句至理名言,句句都非常经典

30句至理名言,句句都非常经典

1、命里有时终须有,命里无时莫强求。谋事在人,成事在天。很多事情是人力不能勉强的,随缘就好。2、忍得一时之气,免得百日之忧。在情绪冲动的情况下,做出的决策伤人伤己,总是让人追悔莫及。能忍住自己的脾气,是一种修养,更是一种能力。3、是非终日有...

工具人是什么意思,工具人是什么梗?

工具人是什么意思,工具人是什么梗?

最近网络上面出现比较多的一个词语就是“工具人”,那么,什么样的人会将他形容成是工具呢?这个是让网友们觉得比较的好奇的,主要是指的什么?在微博上面经常看到有网络语工具人这样的表达,所以引起了很多网友的关注,想要了解这个词语,那么工具人是什么意...

打工人是什么梗出自哪里?打工人的梗为什么这么火?

打工人是什么梗出自哪里?打工人的梗为什么这么火?

近日,看到打工人这词很火,很多小伙伴肯定和我一样,都想知道“打工人”这个词为什么这么火吧?那么,接下来我就跟大家说说打工人是什么梗出自哪里?这词出自哪里无从考证,不过肯定是某些有头脑的网友发明的,至于出自哪位网友?我们一起来了解相关情况吧。...

谈2022年平衡发展策略,我们要平衡的发展

谈2022年平衡发展策略,我们要平衡的发展

2022年解决方案的第二个关键词叫平衡。我们要平衡的发展,长期的发展。你的个人生活,你的公司事业,还有国家的形势,我觉得一定要平衡的去发展,不能说我只赚钱,身体就搞垮,或者说我只赚快钱,但是不关心国家的形势。你看,密室逃脱这个行业,上周国家...