概述
接口 InitializerInterface.java
import android.content.Context;
public interface InitializerInterface {
void init(Context context);
}
实现类 LoggerInitializer.java
import android.content.Context;
import com.hbz.core.initializer.InitializerInterface;
import com.orhanobut.logger.AndroidLogAdapter;
import com.orhanobut.logger.Logger;
public class LoggerInitializer implements InitializerInterface {
@Override
public void init(Context context) {
//代码逻辑
}
}
通过反射调用实现类init方法 InitializerManager .java
import android.content.Context;
import com.hbz.core.utils.ClassUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class InitializerManager {
@SuppressWarnings({"rawtypes", "unchecked"})
public static void init(Context context) {
ArrayListclasses = ClassUtils.getAllClassByInterface(InitializerInterface.class, context.getPackageCodePath(), context.getPackageName());
for (Class clazz : classes) {
try {
//init 方法名 Context.class 参数类型
Method method = clazz.getMethod("init", Context.class);
Object init = clazz.newInstance();
method.setAccessible(true);
method.invoke(init, context);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
遍历实现InitializerInterface接口的全部类 ClassUtils.java
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import dalvik.system.DexFile;
/**
* 查找指定路径下面实现指定接口的全部类
*/
public class ClassUtils {
/**
* @param clazz 接口
* @param packageName 实现类所在的包的包名
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public static ArrayListgetAllClassByInterface(Class clazz, String packagePath, String packageName) {
ArrayListlist = new ArrayList<>();
// 判断是否是一个接口
if (clazz.isInterface()) {
try {
ArrayListallClass = getAllClass(packagePath, packageName);
/**
* 循环判断路径下的所有类是否实现了指定的接口 并且排除接口类自己
*/
for (int i = 0; i < allClass.size(); i++) {
/**
* 判断是不是同一个接口
*/
if (clazz.isAssignableFrom(allClass.get(i))) {
if (!clazz.equals(allClass.get(i))) {
// 自身并不加进去
list.add(allClass.get(i));
}
}
}
} catch (Exception e) {
System.out.println("出现异常");
}
}
return list;
}
/**
* 从一个指定路径下查找所有的类
*
* @param packageName
* @param packagePath
*/
private static ArrayListgetAllClass(String packagePath, String packageName) {
ArrayListlist = new ArrayList<>();
try {
DexFile df = new DexFile(packagePath);//通过DexFile查找当前的APK中可执行文件
Enumerationenumeration = df.entries();
while (enumeration.hasMoreElements()) {
String className = enumeration.nextElement();
if (className.contains(packageName)) {//在当前所有可执行的类里面查找包含有该包名的所有类
Class clazz = Class.forName(className);
list.add(clazz);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (ExceptionInInitializerError e) {
e.printStackTrace();
}
return list;
}
}
调用
InitializerManager.init(this);
proguard-rules.pro 混淆中添加,不然Release模式下找不到文件
-keep class 实现类所在的包路径.**{*;}
最后
以上就是坚定凉面为你收集整理的android 定期调用接口,Android 自动实例化实现某接口的所有类,并调用接口方法...的全部内容,希望文章能够帮你解决android 定期调用接口,Android 自动实例化实现某接口的所有类,并调用接口方法...所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复