网络监控项目,初始化时需要对多个任务类注册到类工厂,方便工厂反射,但根据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; } }