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

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

34资源网2022-07-16429

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

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

分享给朋友:

相关文章

苏格拉底的经典语录有哪些?分享52句苏格拉底经典语录

苏格拉底的经典语录有哪些?分享52句苏格拉底经典语录

很多人问苏格拉底的经典语录有哪些?今天小编就针对大家的疑问,给大家分享52句苏格拉底经典语录,希望对大家有所帮助。…

视频号加粉多少会被推荐?视频号制作方法分享

视频号加粉多少会被推荐?视频号制作方法分享

今天下午,视频号突然暂停申请,让原本打算在视频号大干一场的运营者们感到懵圈。不过据业内人士透露,此次暂停并“不会太久”,很快就会再次上线。…

华为、苹果,为何“盯”上二手机?

华为、苹果,为何“盯”上二手机?

图源:摄图网 编者按:本文来自微信公众号松果财经(ID:songguocaijing1),创业邦经授权转载 继苹果后,华为近日也正式官宣开启二手手机业务,并表示此举是为了提升电子产品的循环再利用。华为官方承诺所售二手手机均为正品且经过严格把…

为了让米粉买到好看的手机壳,雷军投了一家“潮玩工厂”

为了让米粉买到好看的手机壳,雷军投了一家“潮玩工厂”

小米团队花了几个月时间,想要找到一个能DIY打印手机壳的设备却没有找到。直到2020年底,他们在西单大悦城看到玩壳工厂。 “用户需求一直存在,早前也有不少团队尝试开发这样的设备,但都失败了。”玩壳工厂创始人CEO韩冰告诉创业邦。 如今,玩壳…

火了12年,“假洋鬼子”终于翻车了

火了12年,“假洋鬼子”终于翻车了

图源:摄图网 编者按:本文来自微信公众号格隆汇财经热点(ID:glh_finance),作者:万连山,创业邦经授权转载 你肯定看到过这样一幅广告:一个与乔布斯颇有几分相似的神秘洋老头,戴着金丝眼镜,有时叼着烟斗,有时没有,出现在各大高铁站和…

田轩:关于发展新型实体企业的几点思考

田轩:关于发展新型实体企业的几点思考

编者按:本文来自田轩的田字格(ID:tianxuanjiaoshou),作者:田轩,创业邦经授权发布,封面图来自摄图网。 在经济增长模式从要素依赖走向创新驱动型高质量发展的关键期,一手拉紧传统实体产业,另一只手紧贴数字经济发展脉络的新型实体…