欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Android 插件化开发 代码范例

程序员文章站 2022-08-15 18:44:14
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.con....

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

相关标签: Android 插件化