BOB(中国)官方入口-BOB平台在线入口

栏目分类
热点资讯
BOB电竞平台
你的位置:BOB(中国)官方入口-BOB平台在线入口 > BOB电竞平台 > BOB电竞平台 深入理解Android插件化技术原理
BOB电竞平台 深入理解Android插件化技术原理

发布日期:2021-11-18 00:33    点击次数:70

序言 BOB电竞平台

插件化技术最初源于免安置运走apk的思想,这个免安置的apk能够理解为插件。

声援插件化的app能够在运走时添载和运走插件,云云便能够将app中一些不常用的功能模块做成插件,一方面减幼了安置包的大幼,另一方面能够实现app功能的动态扩展;

今天吾们就讲下插件化

一、插件化介绍 1、插件化介绍

在Android编制中,行使是以Apk的样式存在的,行使都必要安置才能行使。但实际上Android编制安置行使的手段相等浅易,其实就是把行使Apk拷贝到编制差别的现在录下、然后把so解压出而已;

常见的行使安置现在录有:

/system/app:编制行使 /system/priv-app:编制行使 /data/app:用户行使

Apk的组成,一个常见的Apk会包含如下几个片面:

classes.dex:Java代码字节码 res:资源现在录 lib:so现在录 assets:静态资产现在录 AndroidManifest.xml:清单文件

其实Android编制在掀开行使之后,也只是开辟进程,然后行使ClassLoader添载classes.dex至进程中,实走对答的组件而已;

那行家能够会想一个题目,既然Android本身也是行使相通逆射的样式添载代码实走,凭什么吾们不克实走一个Apk中的代码呢?

这其实就是插件化的方针,让Apk中的代码能够免安置运走,云云能够带许众利润,最显而易见的上风其实就是议定网络炎更新、炎修复;

2、插件化技术难点 逆射并实走插件Apk中的代码 让编制能调用插件Apk中的组件 正确识别插件Apk中的资源 3、双亲委托机制

ClassLoader调用loadClass手段添载类BOB电竞平台,代码如下:

protected Class<?> loadClass;                             throw e;                 }             }         }                 return clazz;     } 

能够望出ClassLoader添载类时,先查望自身是否已经添载过该类,倘若异国添载过会最先让父添载器往添载,倘若父添载器无法添载该类时才会调用自身的findClass手段添载,该机制很大水平上避免了类的重复添载;

二、插件化详解 1、ClassLoaderInjection

浅易说,插件化场景下,会存在联相符进程中众个ClassLoader的场景:

宿主ClassLoader:宿主是安置行使,运走即自动创建 插件ClassLoader:行使newDexClassLoader创建

吾们称这个过程叫做ClassLoader注入;

完善注入后,一切自宿主的类行使宿主的ClassLoader进走添载,一切自插件Apk的类行使插件ClassLoader进走添载;

而因为ClassLoader的双亲委派机制,实际上编制类会不受ClassLoader的类阻隔机制所影响,云云宿主Apk就能够在宿主进程中行使自于插件的组件类了;

2、RuntimeContainer

ClassLoader注入后,就能够在宿主进程中行使插件Apk中的类,但是吾们都清新Android组件都是由编制调用启动的,未安置的Apk中的组件,是未注册到AMS和PMS的,就益比你直接行使startActivity启动一个插件Apk中的组件,编制会通知你无法找到;

吾们的解决方案很浅易,即运走时容器技术,浅易说就是在宿主Apk中预埋一些空的Android组件,以Activity为例,吾预置一个ContainerActivityextendsActivity在宿主中,并且在AndroidManifest.xml中注册它;

它要做的事情很浅易,就是协助吾们行为插件Activity的容器,它从Intent批准几个参数,别离是插件的差别新闻,如:

pluginName; pluginApkPath; pluginActivityName等,其实最主要的就是pluginApkPath和pluginActivityName,当ContainerActivity启动时,BOB电竞平台吾们就添载插件的ClassLoader、Resource并逆射pluginActivityName对答的Activity类;

当完善添载后ContainerActivity要做两件事:

转发一切自编制的生命周期回调至插件Activity 批准Activity手段的编制调用并转发回编制

吾们能够议定复写ContainerActivity的生命周期手段完善第一步而第二步吾们必要定义一个PluginActivity然后在写插件Apk中的Activity组件时不再让其集成android.app.Activity而是集成自吾们的PluginActivity后面再议定字节码替换自动化完善这部操作后面再说为什么吾们先望假代码;

public class ContainerActivity extends Activity {     private PluginActivity pluginActivity;     @Override     protected void onCreate;     }     // ... } // 插件 `Apk` 中真实写的组件 public class TestActivity extends PluginActivity {     // ...... } 

但也许原理就是这么浅易启动插件组件必要倚赖容器容器负责添载插件组件并且完善双向转发转发自编制的生命周期回调至插件组件同时转发自插件组件的编制调用至编制;

3、ResourceInjection

末了要说的是资源注入其实这一点相等主要Android行使的开发其实崇尚的是逻辑与资源别离的理念一切资源都会被打包到Apk中然后生成一个对答的R类其中包含对一切资源的引用id;

资源的注入并不容易益在Android编制给吾们留了一条后路最主要的是这两个接口:

PackageManager#getPackageArchiveInfo:按照Apk路径解析一个未安置的Apk的PackageInfo; PackageManager#getResourcesForApplication:按照ApplicationInfo创建一个Resources实例;

吾们要做的就是在上面ContainerActivity#onCreate中添载插件Apk的时候用这两个手段创建出一份插件资源实例。详细说就是先用PackageManager#getPackageArchiveInfo拿到插件Apk的PackageInfo有了PacakgeInfo之后吾们就能够本身拼装一份ApplicationInfo然后议定PackageManager#getResourcesForApplication创建资源实例也许代码像云云:

PackageManager packageManager = getPackageManager {     // ... } 

拿到资源实例后吾们必要将宿主的资源和插件资源Merge一下写一个新的Resources类用云云的手段完善自动代理:

public class PluginResources extends Resources {     private Resources hostResources;     private Resources injectResources;     public PluginResources;         }     }     // ... } 

然后吾们在ContainerActivity完善插件组件添载后创建一份Merge资源再复写ContainerActivity#getResources将获取到的资源替换失踪:

public class ContainerActivity extends Activity {     private Resources pluginResources;     @Override     protected void onCreate;         }         return pluginResources;     } } 

云云就完善了资源的注入

4、解决资源冲突

相符并式的资源处理手段会引入资源冲突因为在于差别插件中的资源id能够相通以是解决手段就是使得差别的插件资源拥有差别的资源id;

资源id是由8位16进制数外示外示为0xPPTTNNNN。PP段用区分包空间默认只区分了行使资源和编制资源TT段为资源类型NNNN段在联相符个APK中从0000递添;

总结

市面上的插件化框架实际许众如Tecent的Shadow、Didi的VirtualApk、360的RePlugin。他们各有各的益处不过大体上差不众;

他们大体原理其实都差不众BOB电竞平台运走时会有一个宿主Apk在进程中跑宿弃Apk是真实被安置的行使宿主Apk能够添载插件Apk中的组件和代码运走插件Apk能够肆意炎更新;



BOB电竞平台 BOB体育首页 BOB综合体育在线