1.以下是加载插件的代码 ,

 

package com.example.plugin_core;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Resources;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import dalvik.system.DexClassLoader;

/**
 * 插件化和组件化的区别
 * 组件化需要将代码打包到apk包文件里面
 *
 */
public class PulginManager
{

    private static PulginManager pluginmanager=new PulginManager();
    private Context context;
    /**
     * 加载第三方包的类加载器
     */
    private DexClassLoader dexClassLoader;
    //获得包信息 类
    PackageInfo packageArchiveInfo;
    Resources resources;
    public static PulginManager getInstance(){
        return  pluginmanager;
    }
    public  void  setContext(Context context){
            this.context=context;
    }
   /**
    * @param path  需要类加载器加载包的路径
    */
    public void LoadPlugin(String path){
      /**
       * 解压后的路径
       */
       File plugin= context.getDir("plugin",Context.MODE_PRIVATE);
       /**
       * context.getClassLoader() 父加载器类,加载当前类加载器的加载器的类
       */
        dexClassLoader=new DexClassLoader(path,plugin.getAbsolutePath(),null,context.getClassLoader());
        //得到插件包信息类
         packageArchiveInfo= context.getPackageManager().getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);
        try {
            //资源管理对象,resources 只是代理
            AssetManager assetManager= AssetManager.class.newInstance();
            //反射方法 第二个参数是传入的参数
            Method addAssetPath= assetManager.getClass().getDeclaredMethod("addAssetPath",String.class);
           //通过 assetManager 调用addAssetPath方法,传入参数path
            addAssetPath.invoke(assetManager,path);
            /**
             * 第三个和第四个参数为 手机参数的配置,通过上下文获取
             */
            resources=new Resources(assetManager,context.getResources().getDisplayMetrics(),context.getResources().getConfiguration());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }



    }


    public DexClassLoader getDexClassLoader(){
        return dexClassLoader;
    }

    /**
    * 加载插件方法
    *
    **/
    public void jumpPluginActivity(){

       // PulginManager.getInstance().setContext(Context);
        PulginManager.getInstance().LoadPlugin("");
        //如果包信息类为null
        if(PulginManager.getInstance().packageArchiveInfo==null){
            return;
        }
        //得到Activity info 对象
        ActivityInfo[] activity=packageArchiveInfo.activities;
        if(activity==null || activity.length==0){
            return;
        }
        /**
         * 拿到的是插件中 androidManifest.xml中的第一个。不是启动那一个,所以写插件,规定第0个是 启动Activity
         */
        String activityname =activity[0].name;
        Intent intent=new Intent(context,ProxyActivity.class);
        intent.putExtra("className",activityname);
        context.startActivity(intent);
    }

}

2.插件Activity代码   所有的插件都是使用当前Activity

package com.example.plugin_core;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import dalvik.system.DexClassLoader;

/**
 * 代理Activity ,注册到使用的Activity中
 */

public class ProxyActivity extends Activity {


    PluginInterface pluginInterface;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent=  getIntent();


        String className=intent.getStringExtra("className");
        //类加载器
        try {
           Class<?> aClass=  PulginManager.getInstance().getDexClassLoader().loadClass(className);
           Object actiivty=aClass.newInstance();
           if(actiivty instanceof PluginInterface){
                 pluginInterface= (PluginInterface) actiivty;
                 pluginInterface.attach(ProxyActivity.this);
                 pluginInterface.onCreate(savedInstanceState);
           }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

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

    @Override
    protected void onStart() {
        super.onStart();
        pluginInterface.onStart();
    }

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

    @Override
    protected void onStop() {
        super.onStop();
        pluginInterface.onStop();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        pluginInterface.onDestroy();
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        pluginInterface.onSaveInstanceState(outState);
    }

    @Override
    public void startActivity(Intent intent) {
        String className=intent.getStringExtra("className");
        Intent intent1=new Intent(this,ProxyActivity.class);
        intent1.putExtra("className",className);
        super.startActivity(intent1);
    }

    @Override
    public Resources getResources(){
        return PulginManager.getInstance().resources;
    }

//    @Override
//    public DexClassLoader getDexClassLoader(){
//
//    }


}

 

3.实现插件接口代码,所有插件Activity必须继承自BASE

package com.example.plugin_core;

import android.content.Context;
import android.os.Bundle;
import android.view.MotionEvent;

/**
 * 插件Activity必须实现
 * 使用插件的规则
 *
 *
 */
public interface PluginInterface {

    /**
     *  注入上下文
     */

    void  attach(Context context);
    void  onCreate(Bundle saveIntanceState);
    void  onResume();

    void  onStart();
    void  onPause();
    void  onStop();
    void  onDestroy();
    void  onSaveInstanceState(Bundle outState);
    boolean  onTouchEvent(MotionEvent event);
    void  onBackPressed();

}

 

package com.example.plugin_core;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;

public class PluginBaseAcivity extends Activity implements PluginInterface{


    protected Activity that;

    @Override
    public void attach(Context context) {
        that= (Activity) context;
    }

    @SuppressLint("MissingSuperCall")
    @Override
    public void onCreate(Bundle saveIntanceState) {

    }

    @Override
    public void setContentView(int layoutResID) {
        if(that!=null){
            that.setContentView(layoutResID);
        }else{
            super.setContentView(layoutResID);
        }
    }

    @SuppressLint("MissingSuperCall")
    @Override
    public void onResume() {

    }

    @SuppressLint("MissingSuperCall")
    @Override
    public void onStart() {

    }
    @SuppressLint("MissingSuperCall")
    @Override
    public void onPause() {

    }
    @SuppressLint("MissingSuperCall")
    @Override
    public void onStop() {

    }
    @SuppressLint("MissingSuperCall")
    @Override
    public void onDestroy() {

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {

    }

    @SuppressLint("MissingSuperCall")
    public boolean onTouchEvent(MotionEvent event){

        return false;
    }

    @SuppressLint("MissingSuperCall")
    public  void  onBackPressed(){

    }

    @Override
    public void startActivity(Intent intent) {
        Intent m=new Intent();
        //得到的是传递进来的插件Activity中的包名,启动一个ProxyActivity
        m.putExtra("className",intent.getComponent().getClassName());
        that.startActivity(m);
    }


    public <T extends View> T  findViewById(int id){
        return  that.findViewById(id);
    }


}

 

本文地址:https://blog.csdn.net/liweicai137/article/details/107951098