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