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

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

34资源网2022-07-16344

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

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

分享给朋友:

相关文章

智能电视和普通电视的区别,智能电视好还是普通电视好?

智能电视和普通电视的区别,智能电视好还是普通电视好?

好多人对智能电视和普通的区别还分不大清楚,今天小编就将智能电视和和普通电视做个简单明了的介绍,希望对大家有所帮助。简单的讲,就是智能电视可以看直播电视,也可以点播一些网络电视来看,这个就是最大的区别。当然,有些智能电视还有储存功能,比如,可…

络绎不绝怎么造句?教你用络绎不绝造句

络绎不绝怎么造句?教你用络绎不绝造句

很多人不知道络绎不绝怎么造句?其实用络绎不绝造句有很多的,下面小编整理了29句用络绎不绝造句的句子,希望对大家有借鉴的作用。…

失控玩家怎么样?好看吗?值不值得看?

失控玩家怎么样?好看吗?值不值得看?

每部电影出来都会有人说好看,有人说不好看。只是有些电影拍出来会更加符合大众口味,有些则只适合小部分人看。那么,最近热播的这部失控玩家怎么样?好看吗?值不值得看?今天小编就和大家说说这部适合大众口味的电影。…

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

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

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

闪客快跑2背景音乐(闪客快打andylaw的微博)

闪客快跑2背景音乐(闪客快打andylaw的微博)

《疯狂跑酷》是一款LowPoly(低多边形)画风的跑酷游戏,一场突如其来的大水淹没了城市,而你在游戏中扮演一名刚下班的男子,需要从被水淹没的城市中逃出生天。…

裁员,爱奇艺穿越生死线

裁员,爱奇艺穿越生死线

图源:摄图网 编者按:本文来自微信公众号霞光社(ID:Globalinsights)),作者:麻吉、郭照川、韩夏,创业邦经授权转载 霞光社从多位爱奇艺员工处了解到,本轮裁员罕见覆盖了爱奇艺所有部门,从影业、IP、游戏、电商部门,甚至到经纪公…