注意事项
如果在用Android Studio开发过程中,如果新增了类,扫描不到。只能把APP卸载了,才能扫描到。
可能是Instance Run 的影响。
后面研究一下这篇文章,看看能不能解决
Android 遍历Apk下的所有类文件
package com.trs.nmip.common.util.web.event_submit;
/**
* <pre>
* Created by zhuguohui
* Date: 2024/1/22
* Time: 16:04
* Desc:
* </pre>
*/
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import dalvik.system.BaseDexClassLoader;
import dalvik.system.DexClassLoader;
import dalvik.system.DexFile;
public class AndroidClassScanner {
// 获取某个包名下的所有类名
public static List<String> getClassesInPackage(Context context, String packageName) {
List<String> classNames = new ArrayList<>();
PackageManager packageManager = context.getPackageManager();
try {
// 获取应用信息
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);
// 获取应用 APK 文件的路径
String apkPath = applicationInfo.sourceDir;
// 通过 DexClassLoader 加载 APK 文件
DexClassLoader dexClassLoader = new DexClassLoader(apkPath, context.getCacheDir().getAbsolutePath(), null, context.getClassLoader());
// 获取 Dex 文件的路径
String dexPath = context.getCacheDir() + "/output.dex";
// 将 APK 文件解压到 Dex 文件
DexFile dexFile = DexFile.loadDex(apkPath, dexPath, 0);
// 获取 Dex 文件中的所有类名
Enumeration<String> entries = dexFile.entries();
while (entries.hasMoreElements()) {
String className = entries.nextElement();
classNames.add(className);
}
// 清除 DexClassLoader 缓存
//上述代码在获取完类名后,将 DexClassLoader 设置为 null 并触发垃圾回收,以清除类加载器的缓存。这可能有助于解决新增类无法扫描到的问题
dexClassLoader = null;
System.gc();
} catch (PackageManager.NameNotFoundException | IOException e) {
e.printStackTrace();
}
List<String> needClassNames=new ArrayList<>();
for(String name:classNames){
if(name.startsWith(packageName)){
needClassNames.add(name);
}
}
return needClassNames;
}
}