Android ClassesReader 扫描指定包下所有Class

Android ClassesReader 扫描指定包下所有Class

    • 前言
    • 类读取器 ClassesReader.java
    • 测试代码 MainActivity.java
    • 测试成功

前言

1、最近项目中Service创建需要扫描某个包下的事件组件,使用Java反射技术实例化对象进行事件注册,如果不使用包扫描则需要每个组件都写一行代码注册未免太冗余,而且会忘记注册无法监听事件,使用包扫描则可以事半功倍!

类读取器 ClassesReader.java



package com.example.myapplication;

import android.content.Context;


import java.io.File;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import dalvik.system.DexFile;

/**
 * 类读取器
* 读取某个包下所有类
*/
public final class ClassesReader { /** * 获取应用程序下的所有Dex文件 * * @param context 上下文 * @return Set */ public static Set<DexFile> applicationDexFile(Context context) { return applicationDexFile(context.getPackageCodePath()); } /** * 获取应用程序下的所有Dex文件 * * @param packageCodePath 包路径 * @return Set */ public static Set<DexFile> applicationDexFile(String packageCodePath) { Set<DexFile> dexFiles = new HashSet<>(); File dir = new File(packageCodePath).getParentFile(); File[] files = dir.listFiles(); for (File file : files) { try { String absolutePath = file.getAbsolutePath(); if (!absolutePath.contains(".")) continue; String suffix = absolutePath.substring(absolutePath.lastIndexOf(".")); if (!suffix.equals(".apk")) continue; DexFile dexFile = createDexFile(file.getAbsolutePath()); if (dexFile == null) continue; dexFiles.add(dexFile); } catch (Exception e) { e.printStackTrace(); } } return dexFiles; } /** * 创建DexFile文件 * * @param path 路径 * @return DexFile */ public static DexFile createDexFile(String path) { try { return new DexFile(path); } catch (IOException e) { return null; } } /** * 读取类路径下的所有类 * * @param packageName 包名 * @param context 包路径 * @return List */ public static List<Class<?>> reader(String packageName, Context context) { return reader(packageName, context.getPackageCodePath()); } /** * 读取类路径下的所有类 * * @param packageName 包名 * @param packageCodePath 上下文 * @return List */ public static List<Class<?>> reader(String packageName, String packageCodePath) { List<Class<?>> classes = new ArrayList<>(); Set<DexFile> dexFiles = applicationDexFile(packageCodePath); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); for (DexFile dexFile : dexFiles) { if (dexFile == null) continue; Enumeration<String> entries = dexFile.entries(); while (entries.hasMoreElements()) { try { String currentClassPath = entries.nextElement(); if (currentClassPath == null || currentClassPath.isEmpty() || currentClassPath.indexOf(packageName) != 0) continue; Class<?> entryClass = Class.forName(currentClassPath, true, classLoader); if (entryClass == null) continue; classes.add(entryClass); } catch (Exception e) { e.printStackTrace(); } } } return classes; } }

测试代码 MainActivity.java


package com.example.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivityClassesReader";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        List<Class<?>> reader = ClassesReader.reader("com.example.myapplication.component", this);
        for (Class<?> c : reader) Log.i(TAG, "onCreate -> ClassName: " + c.getName());
    }
}


测试成功

Android ClassesReader 扫描指定包下所有Class_第1张图片

你可能感兴趣的:(Android)