Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android插件化学习之路(五)之代理Activity

Android插件化学习之路(五)之代理Activity

作者头像
老马的编程之旅
发布于 2022-06-22 02:10:33
发布于 2022-06-22 02:10:33
41800
代码可运行
举报
文章被收录于专栏:深入理解Android深入理解Android
运行总次数:0
代码可运行

简单模式中,使用ClassLoader加载外部的Dex或Apk文件,可以加载一些本地APP不存在的类,从而执行一些新的代码逻辑。但是使用这种方法却不能直接启动插件里的Activity。

启动插件中Activity的两个主要问题

Activity等组件是需要在Manifest中注册后才能以标准Intent的方式启动的,通过ClassLoader加载并实例化的Activity实例只是一个普通的Java对象,能调用对象的方法,但是它没有生命周期,而且Activity等系统组件是需要Android的上下文环境的(Context等资源),没有这些东西Activity根本无法工作。

使用插件APK里的Activity需要解决两个问题: 1. 如何使插件APK里的Activity具有生命周期; 2. 如何使插件APK里的Activity具有上下文环境(使用R资源); 代理Activity模式为解决这两个问题提供了一种思路。

代理Activity模式

这种模式的特点是:主项目APK注册一个代理Activity(命名为ProxyActivity),ProxyActivity是一个普通的Activity,但只是一个空壳,自身并没有什么业务逻辑。每次打开插件APK里的某一个Activity的时候,都是在主项目里使用标准的方式启动ProxyActivity,再在ProxyActivity的生命周期里同步调用插件中的Activity实例的生命周期方法,从而执行插件APK的业务逻辑。

ProxyActivity + 没注册的Activity = 标准的Activity

第二个问题,我们在上一篇博客中已经解决了,下面我们来分析使插件APK里的Activity具有生命周期的问题

处理插件Activity的生命周期

目前还真的没什么办法能够处理这个问题,一个Activity的启动,如果不采用标准的Intent方式,没有经历过Android系统Framework层级的一系列初始化和注册过程,它的生命周期方法是不会被系统调用的(除非你能够修改Android系统的一些代码,而这已经是另一个领域的话题了,这里不展开)。

那我们可以在主项目里创建一个ProxyActivity,再由它去代理调用插件Activity的生命周期方法(这也是代理模式叫法的由来)。用ProxyActivity(一个标准的Activity实例)的生命周期同步控制插件Activity(普通类的实例)的生命周期,同步的方式可以有下面两种:

• 在ProxyActivity生命周期里用反射调用插件Activity相应生命周期的方法,简单粗暴。 • 把插件Activity的生命周期抽象成接口,在ProxyActivity的生命周期里调用。另外,多了这一层接口,也方便主项目控制插件Activity。

用反射调用插件Activity相应生命周期

我们要在代理activity中去反射apk中activity的所有生命周期的方法,然后将activity的生命周期和代理activity的生命周期进行同步。首先,反射activity生命周期的所有方法,还反射了onActivityResult这个方法,尽管它不是典型的生命周期方法,但是它很有用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1.  protected void instantiateLifecircleMethods(Class<?> localClass) {  
2.      String[] methodNames = new String[] {  
3.              "onRestart",  
4.              "onStart",  
5.              "onResume",  
6.              "onPause",  
7.              "onStop",  
8.              "onDestory"  
9.      };  
10.     for (String methodName : methodNames) {  
11.         Method method = null;  
12.         try {  
13.             method = localClass.getDeclaredMethod(methodName, new Class[] { });  
14.             method.setAccessible(true);  
15.         } catch (NoSuchMethodException e) {  
16.             e.printStackTrace();  
17.         }  
18.         mActivityLifecircleMethods.put(methodName, method);  
19.     }  
20.   
21.     Method onCreate = null;  
22.     try {  
23.         onCreate = localClass.getDeclaredMethod("onCreate", new Class[] { Bundle.class });  
24.         onCreate.setAccessible(true);  
25.     } catch (NoSuchMethodException e) {  
26.         e.printStackTrace();  
27.     }  
28.     mActivityLifecircleMethods.put("onCreate", onCreate);  
29.   
30.     Method onActivityResult = null;  
31.     try {  
32.         onActivityResult = localClass.getDeclaredMethod("onActivityResult",  
33.                 new Class[] { int.class, int.class, Intent.class });  
34.         onActivityResult.setAccessible(true);  
35.     } catch (NoSuchMethodException e) {  
36.         e.printStackTrace();  
37.     }  
38.     mActivityLifecircleMethods.put("onActivityResult", onActivityResult);  
39. }  

其次,同步生命周期,主要看一下onResume和onPause,其他方法是类似的。看如下代码,很好理解,就是当系统调用代理activity生命周期方法的时候,就通过反射去显式调用apk中activity的对应方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1.  @Override  
2.  protected void onResume() {  
3.      super.onResume();  
4.      Method onResume = mActivityLifecircleMethods.get("onResume");  
5.      if (onResume != null) {  
6.          try {  
7.              onResume.invoke(mRemoteActivity, new Object[] { });  
8.          } catch (Exception e) {  
9.              e.printStackTrace();  
10.         }  
11.     }  
12. }  
13.   
14. @Override  
15. protected void onPause() {  
16.     Method onPause = mActivityLifecircleMethods.get("onPause");  
17.     if (onPause != null) {  
18.         try {  
19.             onPause.invoke(mRemoteActivity, new Object[] { });  
20.         } catch (Exception e) {  
21.             e.printStackTrace();  
22.         }  
23.     }  
24.     super.onPause();  
25. }  

把插件Activity的生命周期抽象成接口,在ProxyActivity的生命周期里调用

采用反射去管理activity的生命周期,这样存在一些不便,比如反射代码写起来复杂,并且过多使用反射有一定的性能开销。针对这个问题,可以采用接口机制,将activity的大部分生命周期方法提取出来作为一个接口(DLPlugin),然后通过代理activity(DLProxyActivity)去调用插件activity实现的生命周期方法,这样就完成了插件activity的生命周期管理,并且没有采用反射,当我们想增加一个新的生命周期方法的时候,只需要在接口中声明一下同时在代理activity中实现一下即可.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface DLPlugin {

    public void onStart();
    public void onRestart();
    public void onActivityResult(int requestCode, int resultCode, Intent data);
    public void onResume();
    public void onPause();
    public void onStop();
    public void onDestroy();
    public void onCreate(Bundle savedInstanceState);
    public void setProxy(Activity proxyActivity, String dexPath);
    public void onSaveInstanceState(Bundle outState);
    public void onNewIntent(Intent intent);
    public void onRestoreInstanceState(Bundle savedInstanceState);
    public boolean onTouchEvent(MotionEvent event);
    public boolean onKeyUp(int keyCode, KeyEvent event);
    public void onWindowAttributesChanged(LayoutParams params);
    public void onWindowFocusChanged(boolean hasFocus);

在代理类DLProxyActivity中的实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
...
    @Override
    protected void onStart() {
        mRemoteActivity.onStart();
        super.onStart();
    }

    @Override
    protected void onRestart() {
        mRemoteActivity.onRestart();
        super.onRestart();
    }

    @Override
    protected void onResume() {
        mRemoteActivity.onResume();
        super.onResume();
    }

    @Override
    protected void onPause() {
        mRemoteActivity.onPause();
        super.onPause();
    }

    @Override
    protected void onStop() {
        mRemoteActivity.onStop();
        super.onStop();
    }
...

通过以上两种方式,就可以解决插件Activity的生命周期的问题,现在一般推荐第二种方式。

参考文章:http://blog.csdn.net/singwhatiwanna/article/details/23387079

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-11-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android插件化学习之路(九)之DynamicLoadApk 源码解析(下)
承接上一篇,继续分析DynamicLoadApk 源码。 4.2 DLPluginPackage 插件信息对应的实体类,主要属性如下:
老马的编程之旅
2022/06/22
2880
Android插件化学习之路(九)之DynamicLoadApk 源码解析(下)
Android插件化技术之旅 1 开篇 - 实现启动插件与调用插件中的Activity和Service
Android技术如今已很成熟了,组件化、插件化、热修复等等框架层出不穷,如果只停留在单纯的会用框架上,技术永远得不到成长,只有懂得其原理,能够婉婉道来,能够自己手动写出,技术才会得到成长,与其焦虑未来,不如把握现在。本篇将手写教大家写出插件化框架,插件化技术是Android高级工程师必备的技术之一,懂其思想,知其原理。本篇专题将由10篇文章来详细的讲解插件化技术,深耕一个技术领域,才能懂得如何更广阔的横向发展。
用户3045442
2019/01/09
1.3K0
【Android 插件化】“ 插桩式 “ 插件化框架 ( 代理 Activity 组件开发 )
【Android 插件化】插件化简介 ( 组件化与插件化 ) 【Android 插件化】插件化原理 ( JVM 内存数据 | 类加载流程 ) 【Android 插件化】插件化原理 ( 类加载器 ) 【Android 插件化】“ 插桩式 “ 插件化框架 ( 原理与实现思路 ) 【Android 插件化】“ 插桩式 “ 插件化框架 ( 类加载器创建 | 资源加载 ) 【Android 插件化】“ 插桩式 “ 插件化框架 ( 注入上下文的使用 ) 【Android 插件化】“ 插桩式 “ 插件化框架 ( 获取插件入口 Activity 组件 | 加载插件 Resources 资源 ) 【Android 插件化】“ 插桩式 “ 插件化框架 ( 运行应用 | 代码整理 )
韩曙亮
2023/03/29
7930
自己动手写Android插件化框架
本文旨在通过两个实例直观的说明插件的实现原理以加深对插件内开发的理解,因此不会深入探讨背景和原理,代码也尽量专注于核心逻辑。
达文西
2018/10/06
1.6K0
Activity状态和生命周期方法
前面两期我们学习了Activity的创建和注册、以及启动和关闭,也学会了重写onCraete方法,这些知识在实际开发中远远不够,还需要学习了解更多。 生命周期就是一个对象从创建到销毁的过程,每一个对象都有自己的生命周期。同样, Activity也具有相应的生命周期。 一、Activity状态 一个Android应用程序往往包含多个Activity,当Activity处于Android应用中运行时,每个Activity的状态都不一样。Activity的活动状态由Android以Act
分享达人秀
2018/02/05
2.1K0
Activity状态和生命周期方法
Activity 使用详解
本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:
用户1119350
2019/08/05
8020
Activity 使用详解
Android 四大组件之Activity生命周期
写这篇博文之前,已经对android有一定的了解和认识。这篇博文主要讲述android的Activity的生命周期,这是android开发者必须掌握的知识。android的Activity组件拥有7个生命周期:onCreate()、onStart()、onResume()、onPause()、onStop()、onDestory()、onReStart()。 这7个生命周期分别在4个特定阶段进行调用。 开始Activity:当Activity开始运行的时候依次执行3个生命周期:onCreate、onStar
水击三千
2018/02/27
8090
Android 四大组件之Activity生命周期
android之activity的生命周期详解
刚在看mars老师的视频,看到activity的生命周期,就看了一下,总结了一下.下面是各函数的调用时机
全栈程序员站长
2022/07/20
6980
android之activity的生命周期详解
Android开发工程师文集-Activity生命周期,启动方式,Intent相关介绍,Activity详细讲解
大家好,我是 Vic,今天给大家带来Android开发工程师文集-Activity生命周期,启动方式,Intent相关介绍,Activity详细讲解的概述,希望你们喜欢
达达前端
2019/07/03
8040
Activity入门—Activity生命周期及三种状态+案例[通俗易懂]
1 onCreate( )这是必须要写的方法,此方中主要是对activity进行ui的加载
全栈程序员站长
2022/09/22
7K0
Activity入门—Activity生命周期及三种状态+案例[通俗易懂]
Android开发之Activity的生命周期以及加载模式
本篇博客就来好好的搞一下Activity的生命周期,如果搞过iOS的小伙伴的话,Activity的生命周期和iOS中ViewController的生命周期非常类似。生命周期,并不难理解。一个人的生命周期莫过于生老病死,花儿的生命周期就是花开花谢了。在Android中Activity的生命周期莫过于Activity的创建到消亡的过程了。本篇博客就会介绍Activity生命周期中的不同阶段,通过实例的形式来窥探一下Activity的生命周期。搞明白Activity的生命周期是至关重要的,因为只有搞明白每个生命周
lizelu
2018/01/11
1.2K0
Android开发之Activity的生命周期以及加载模式
Android Activity详解(一)
在此之前,我们新建一个项目,代码非常简单,两个活动之间相互跳转(本来想做GIF图的,不会~~~~(>_<)~~~~)
萬物並作吾以觀復
2018/09/13
9970
Android Activity详解(一)
Activity生命周期
我们来回顾一下关于Activity的知识点,这个是面试中最常问的问题之一,Activity也是Android中四大组件,最重要的一个组件,我们在实际开发中,需要我们开发者理解它的生命周期还有对启动模式特殊场景的使用。 生命周期 那七个方法你不可能不熟悉: onCreate->onRestart->onStart->onResume->onPause->onStop->onDestory Activity的创建和销毁都会回调这七个方法: onCreate:Activity创建成功回调。 onRestart:A
巫山老妖
2018/07/20
5780
探究活动Activity(2)界面跳转及生命周期
1.使用Intent在活动中跳转 首先我们新建一个名为MyActivityTest的项目,其中我们将活动命名为FirstActivity,布局命名为first_layout.xml,记得勾选Generate Layout File ,如下图所示
晨曦_LLW
2020/09/25
1.2K0
1-AI--Activity生命周期
1.ActivityLifeCycle:测试生命周期的Activity 2.CommonActivity是一个普通的Activity 3.DialogActivity是对话框型的Activity
张风捷特烈
2018/09/26
4710
Android 四大组件学习之Activity五
上几次课学习了,如何创建一个Activity, 如何去用一个Activity去启动另外一个Activity, 以及传值,得到返回值等。
DragonKingZhu
2022/05/08
3030
Android 四大组件学习之Activity五
关于Activity生命周期的小结
开头先说一下写这篇博客的初衷,由于博主在找实习的过程中面试经常被问到Activity生命周期有关的问题,所以特此写一篇博客来记一下。
俞其荣
2022/07/28
3160
关于Activity生命周期的小结
详解 Android Activity 生命周期
  从以下几个方面详细说一下Activity的生命周期:  1.回到主屏幕再打开和退出程序的时候。   2.屏幕旋转的时候。   3.打开其它的Activity的情况。   4.打开一个Layou透
lpxxn
2018/01/31
9280
详解 Android Activity 生命周期
Android四大组件之一Activity详解
Activity是Android应用的重要组成单元之一(另外三个是Service、BroadcastReceiver和ContentProvider),而Activity又是Android应用最常见的组件之一。通常一个Android应用需要N个Activity组成,Activity主要负责与用户交互
提莫队长
2019/03/01
6890
Android四大组件之一Activity详解
一次搞定【Activity生命周期】
Activity生命周期说难也不难,无非那么7个阶段,可是初学者总是搞不清楚怎么办?最好的方法就是跟着这个demo练习一次,亲手操作更易理解,一次搞定Activity生命周期!!
张拭心 shixinzhang
2022/11/30
3520
相关推荐
Android插件化学习之路(九)之DynamicLoadApk 源码解析(下)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档