• Andriod 插件化初识


    一、目的

    主app加载第三方apk提供的view,当view有变化时,只需更换三方app。优点:充分解耦,方便维护

    二、实施

    1、三方app需提供

    (1)action:android.intent.action.CREATE_THIRD

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@style/TranslucentTheme">
        <intent-filter>
           <action android:name="android.intent.action.MAIN" />
           <action android:name="android.intent.action.CREATE_THIRD" />
           <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    (2)对外暴露的静态方法:

        public static View createThirdView(Context hostContext, Context context, Bundle bundle) {
            Log.i("============", "createThirdView");
            View view = LayoutInflater.from(context).inflate(R.layout.layout_view, null, false);
            return view;
        }

    2、宿主app

    (1)通过action查找revolveinfo信息,revolveinfo可提供包名和类名

    (2)通过revolveinfo提供的包名,创建插件context

    (3)插件context创建类加载器,配合类名获取类对象

    (4)通过反射,由类获取到对应的方法,并调用方法

            var action = "third_action"
            var funcName = "third_method"
            var pluginView: View? = null
            val packageManager = application.packageManager
            val intent = Intent(action)
            //1.查找action对应的resolveInfo信息
            val resolveInfoList =
                packageManager.queryIntentActivities(intent, PackageManager.GET_META_DATA)
            if (resolveInfoList.isNotEmpty()) {
                val resolveInfo = resolveInfoList[0]
                if (resolveInfo.activityInfo == null) {
                    return null
                }
                val packageName = resolveInfo.activityInfo.packageName
                val className = resolveInfo.activityInfo.name
              
                //2.创建插件上下文
                val pluginContext = this.createPackageContext(
                    packageName,
                    Context.CONTEXT_INCLUDE_CODE or Context.CONTEXT_IGNORE_SECURITY
                )
                //3.通过插件上下文,创建类加载器
                val pluginClassLoader =
                    PathClassLoader(pluginContext.packageResourcePath, pluginContext.classLoader)
                //4.通过类加载器加载类,并获取方法
                val loadClass = pluginClassLoader.loadClass(className)
                val localMethod = loadClass.getMethod(
                    funcName,
                    Context::class.java,
                    Context::class.java,
                    Bundle::class.java
                )
                //5.通过反射调用方法,获取view
                pluginView =
                    localMethod.invoke(
                        loadClass,
                        application.applicationContext,
                        pluginContext,
                        Bundle()
                    ) as View?
            }
  • 相关阅读:
    fedora-coreos 试用podman
    博客主题更新了
    C stdarg.h:可变参数va_list、va_arg等宏的使用及原理简介
    静态、动态链接库的生成及使用
    notfastjson项目介绍
    The ANSI C Programming Language:C语言预处理机制
    语法分析:LL(1)语法分析的实现及扩展的巴科斯范式
    语法分析:LL(1)分析
    计算机系统基础:计算机系统概述
    计算机系统基础:数据的表示和存储
  • 原文地址:https://www.cnblogs.com/suiyilaile/p/16598681.html
Copyright © 2020-2023  润新知