Android 插件开发框架 总结

2023-09-22 14:04:23
1)类转载器ClassLoader:
 标准的javaSDK中有ClassLoader类,ClassLoader 加载类的方式常称为双亲委托,ClassLoader.java 具体代码如下:
protectedClass<?>loadClass(StringclassName,booleanresolve)throwsClassNotFoundException{
    Class<?>clazz=findLoadedClass(className);
 
    if(clazz==null){
        try{
            clazz=parent.loadClass(className,false);
        }catch(ClassNotFoundExceptione){
            // Don't want to see this.
        }
        if(clazz==null){
            clazz=findClass(className);
        }
    }
    returnclazz;
}

 
loadClass 会先看这个类是不是已经被 loaded 过,没有的话则去他的 parent 去找,如此递归,称之为双亲委托。
在Android中可以动态加载,但无法像Java中那样方便动态加载jar。原因:Android的虚拟机(Dalvik VM)是不认识Java打出jar的byteCode,需要通过dx工具来优化转换成Dalvik byteCode才行。项目中,引入其他Jar的内容都被打包进了classes.dex。dex文件是Android系统将所需要的所有Class文件重新打包,打包时并进行了优化。
DexClassLoader 可以加载jar/apk/dex,也可以从SD卡中加载.
PathClassLoader 只能加载已经安装到Android系统中的apk文件。
2)插件框架如何动态加载Activity。
由于Activity需要在清单文件注册了才能使用,要么注册一个Activity基类,供插件中的Activity继承,在这个基类里做动态加载的核心逻辑,这就要求插件必须依赖某种API类库。
要么就是依赖倒转,不让插件依赖框架API,而是反过来,自动生成一个Activity类依赖(继承)插件中的Activity,这个自动生成的类就叫PluginActivity
并且声明在框架的清单文件中,如下: 

<activity name="androidx.pluginmgr.PluginActivity" /> 
原理1:Activity的启动都通过Instrumentation进行一步代理,重写Instrumentation可以得到Activity生命周期。重写 newActivity 方法构造自己的Activity对象返回给系统,这样以后onCreate等事件都入自动传入我们的Activity。也就是 在主程序的manifest中声明一个PluginActivity,当启动插件中activity A 时我们在Instrumentation的execStartActivity方法中告诉系统我要启动PluginActivity,但是当系统真正构造PluginActivity对象时我们在newActivity方法中 new A()对象返回系统。
插件开发实践:
1  关于服务
这里所说的服务是指插件项目或者主项目提供的某种功能,这种功能的调用和实现一般是跨项目的存在的。
插件和主项目之间的服务采用接口依赖的方式。
跨项目调用服务,该服务必须在插件框架中注册。
原则是:谁提供服务,谁注册服务,谁实现服务接口。调用服务只需要提供自己业务对应数据,并调用该接口的方法
2 关于接口
接口的设计目的是让插件和主项目之间的服务采用该接口相互依赖。同时,通过接口方法提供跨项目间传递数据的功能。
通过接口方法传递数据方式无非两种, 一种是通过方法的参数来set,一种是通过get方法的返回值
对于依赖接口的设计,尽量保证简洁,高效,低的耦合性。
3 项目中的应用:
   1 ) 首先要搞清楚谁来提供服务,要明确该服务需要哪些数据,如何来调用。
         然后根据该服务写对应的依赖服务接口,以及接口中定义的抽象方法。
  2 ) 对于服务提供方:  实现该服务接口,向框架注册该服务。
         注册操作应该在插件的入口中执行。插件入口配置:Bundle-Activator=com.netease.plugin.webcontainer.MyActivator
        // 注册服务
       bundleContext.registerService(WebViewService.class.getName(),  new WebViewServiceImpl(), null);
          对于服务使用方:首先获取该服务,然后调用该服务的提供的方法。
        //获取服务
       mWebViewService = (WebViewService) PluginUtils  .getService(WebViewService.class.getName());
  
注意: 在插件项目中提供的服务,主项目一般先启动,然后在使用该插件的服务之前一定要保证让插件项目启动起来,并注册了该服务。
3) 在服务接口的实现类中的方法中启动对应的activity来完成该功能。 但是如果方法中没有获取到content,
   可以使用框架提供的全局的context即StartActivityService来跳转。
      
  StartActivityService sas = (StartActivityService) PluginUtils  .getService(StartActivityService.class.getName());
        Intent intent = new Intent();
        intent.setClassName(PLUGIN_ID, WebViewActivity.class.getName());
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        sas.StartActivity(PLUGIN_ID, intent);
更多推荐

linux下特定usb设备的权限设置

文章目录背景查找资料解决方案背景目前我在Ubuntu下使用一个USB热成像摄像头,通过调用它的sdk进行图像的采集以及获取对应像素点的温度。假设我现在的测试程序名称为MyApp。当我用下面的命令运行时,程序是正常运行且能从热成像仪采集图像sudo./MyApp但是当我以下面的命令运行时,./MyApp会报错:libir

用例图学习

用例图是什么用例图(UseCaseDiagram)是UML(统一建模语言)中的一种行为图,用于描述系统的功能和用户(或其他外部实体)与系统之间的交互。用例图是一种高级图,通常用于捕捉系统的需求,展示系统的功能和用户需求之间的关系,以及不同用例之间的依赖。以下是用例图中常见的元素和概念:用例(UseCase):用例表示系

六角形锌饼的尺寸及其允许偏差

声明本文是学习GB-T3610-2010电池锌饼.而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们1范围本标准规定了电池锌饼的产品分类、要求、试验方法、检验规则及标志、包装、运输、贮存、质量证明书和合同(或订货单)等内容。本标准适用于制造锌-锰干电池负极整体锌筒用的锌饼。2规范性引用文件下列文件对于

C语言之链表

C语言之链表定义:链表是一种物理存储上非连续,数据元素的逻辑顺序通过链表中的指针链接次序,实现的一种线性存储结构。特点:链表由一系列节点(链表中每一个元素称为节点)组成,节点在运行时动态生成(malloc),每个节点包括两个部分:一个是存储数据元素的数据域另一个是存储下一个节点地址的指针域//链表的构成typedefs

解决方案| anyRTC远程检修应用场景

背景在这个科技飞速发展的时代,各行各业都要求高效运转。然而,当出现问题时,我们却常常因为无法及时解决而感到困扰,传统解决问题的方式是邀请技术人员现场解决问题,如果技术人员解决不了,还要邀请专家从其他城市到现场解决,这中间会流失很多时间,影响生产效率。现在,anyRTC推出一站式远程检修方案,让检修得到最专业、最快速的的

el-select 下拉框全选、多选的几种方式组件

组件一、基础多选适用性较广的基础多选,用Tag展示已选项<template><el-selectv-model="value1"multipleplaceholder="请选择"><el-optionv-for="iteminoptions":key="item.value":label="item.label":va

windows批处理 将当前路径添加到Windows的`PATH`环境变量中 %~dp0

将当前路径添加到Windows的PATH环境变量中要将当前路径添加到Windows的PATH环境变量中,可以使用以下方法:使用命令行:打开命令提示符(CommandPrompt)或PowerShell,然后执行以下命令:setxPATH"%PATH%;C:\Your\Current\Directory"这会将当前路径(

【面试刷题】——C++四种类型转化

C++支持多种类型转换操作,其中包括四种主要类型转换方式:隐式类型转换(ImplicitConversion):隐式类型转换是自动发生的类型转换,由编译器自动完成。它用于处理不同数据类型之间的运算,例如将整数和浮点数相加时,整数会隐式地转换为浮点数。例如,将int转换为double或将float转换为int都是隐式类型

LinuxShell命令行及脚本编程实例详解_笔记

LinuxShell命令行及脚本编程实例详解Linux典藏大师系列丛书shell脚本的构成:1.shell关键字if...thenelse;for...done;whiledodone2.shell命令export,echo,exit,pwd,return3.linux命令datarmmkdircd4.文本处理功能aw

39 | selenium基础架构,UI测试架构

什么是测试基础架构?测试基础架构指的是,执行测试的过程中用到的所有基础硬件设施以及相关的软件设施。因此,我们也把测试基础架构称之为广义的测试执行环境。通常来讲,测试基础架构主要包括以下内容:执行测试的机器;测试用例代码仓库;发起测试执行的JenkinsJob;统一的测试执行平台;测试用例执行过程中依赖的测试服务,比如提

百望云获评ITShare数智未来创新峰会“年度数字化优秀服务商”大奖

近日,百望云应邀出席“新能源-新制造暨汽车数智未来创新峰会”,凭借在数字化领域优秀的服务能力和丰富的落地成果,成功获评“年度数字化优秀服务商”,这也是市场对百望云在赋能企业数字化转型和产品创新领域的再度认可!在“数智创新未来”的主题下,百望云也与众多行业知名企业分享了财税数字化转型成功经验,共襄盛会,齐瞻未来。数智未来

热文推荐