网络监控项目,初始化时需要对多个任务类注册到类工厂,方便工厂反射,但根据classloader规则,无法初始化与入口类无关的类,因此需要遍历类名,强制加载:
public class TaskRunnableFactory {
public static abstract class TaskRunnable {
protected RunStat runStat = RunStat.WAIT_FOR_RUN;
protected Task task;
protected Context context;
protected void setTask(Context cont, Task task)
{
context = cont;
this.task = task;
}
protected static HashMap<TaskType, String> prefixMap= new HashMap<TaskType, String>();
public RunStat getRunStat() {
return runStat;
}
public abstract void run();
public abstract int result();
public abstract String report();
}
static private HashMap<TaskType, Class<?>> runMap;
public TaskRunnableFactory(Context cont)
{
try {
String path = cont.getPackageResourcePath();
DexFile df = new DexFile(path);
for (Enumeration<String> iter = df.entries(); iter.hasMoreElements();) {
String s = iter.nextElement();
if (s.startsWith("jd.net.check.runnable.") && !s.contains("$")) {
Class.forName(s);
}
}
} catch (Exception e) {
}
}
static public void registType(TaskType type, Class<?> runClass, String cmd){
registType(type, runClass);
TaskRunnable.prefixMap.put(type, cmd);
}
static public void registType(TaskType type, Class<?> runClass){
if(runMap==null) runMap = new HashMap<TaskType, Class<?>>();
runMap.put(type, runClass);
}
public TaskRunnable createRunnalbe(Context cont, Task task) {
try {
Class<?> runnableClass = runMap.get(task.getType());
if (runnableClass == null)
return null;
TaskRunnable run = (TaskRunnable) runnableClass.newInstance();
run.setTask(cont, task);
return run;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public class CmdRunnable extends TaskRunnable {
static {
TaskRunnableFactory.registType(TaskType.CMD, CmdRunnable.class);
TaskRunnableFactory.registType(TaskType.GET_GETPROP, CmdRunnable.class, "getprop");
TaskRunnableFactory.registType(TaskType.GET_NETSTAT, CmdRunnable.class, "netstat");
TaskRunnableFactory.registType(TaskType.GET_ROUTE, CmdRunnable.class, "cat /proc/net/route");
TaskRunnableFactory.registType(TaskType.RUN_PS, CmdRunnable.class, "ps");
TaskRunnableFactory.registType(TaskType.RUN_IFCONFIG, CmdRunnable.class, "ifconfig");
TaskRunnableFactory.registType(TaskType.RUN_PING, CmdRunnable.class, "ping");
}
private ExecRes res = new ExecRes();
@Override
public void run() {
runStat = RunStat.RUNNING;
String cmd = String.format("%s %s", prefixMap.get(task.getType()), task.getCmd());
SysUtils.exec(cmd, res);
runStat = (res.ret<0)?RunStat.ERROR:RunStat.DONE;
}
@Override
public int result() {
return res.ret;
}
@Override
public String report() {
return res.output;
}
}