您的位置:首页 > 编程语言 > Java开发

Android 与 JDK 下查找包下的类

2015-08-05 23:49 411 查看

Android 与 JDK 下查找包下的类

本文的标题可以看出,Android与JDK查找包下的类并列标题,主要原因是最近在写的一个项目,相同的代码可能在不同的平台执行。而在JDK环境测试OK的代码到Android设备上就不正常了,于是查找了些资料。具体原因因为ClassLoader.getResource(name)实现不同。最终实现如下,不同平台进行了封装,只需要调用以下代码即可:

List<String> classes = ClassScannerFactory.getScanner().scannClassess("cn.canney");


先看下项目结构



下面上代码

/**
* 类扫描器
* @author Canney Chen
*
*/
public abstract class ClassScanner {

/**
* 扫描包下的类
* @param pck
* @return
* @throws Exception
*/
public List<String> scannClassess(String pck) throws Exception{
if(!checkPackage(pck)){
throw new Exception("package invalid:" + pck);
}
return onScannClasses(pck);
}

private boolean checkPackage(String pck){
if(pck == null || "".equals(pck)){
return false;
}else if(pck.startsWith(".") || pck.endsWith(".")){
return false;
}
return true;
}

protected abstract List<String> onScannClasses(String pck) throws Exception;
}


package cn.canney.util;

public class ClassScannerFactory {
public static ClassScanner getScanner(){
if(isOnAndroid()){
return new AndroidClassScanner();
}else{
return new CommonClassScanner();
}
}

public static boolean isOnAndroid(){
return System.getProperty("java.runtime.name").contains("Android");
}
}


/**
* {@link Class#getResource(String)}能正常加载资源的类扫描器实现
* @author Canney Chen
*
*/
public class CommonClassScanner extends ClassScanner {

@Override
public List<String> onScannClasses(String pck) throws Exception {
List<String> classes = new ArrayList<String>();
scanClasses(pck, classes);
return classes;
}

private void scanClasses(String pck, List<String> classes) throws URISyntaxException{
String path = "/" + pck.replace(".", "/");
URL url = ClassScanner.class.getResource(path);
File pckDir = new File(url.toURI());
File[] fs = pckDir.listFiles();
if(fs == null){
return ;
}

for (int i = 0; i < fs.length; i++) {
File f = fs[i];
String fillPck = new StringBuffer(pck).append(".").append(f.getName()).toString();
if(f.isFile()){
String className = fillPck.replace(".class", "");
classes.add(className);
}else{
scanClasses(fillPck, classes);
}
}
}
}


/**
* Android 类扫描器实现
* @author Canney Chen
*
*/
public class AndroidClassScanner extends ClassScanner {

@Override
protected List<String> onScannClasses(String pck) throws Exception {
DexFile df = new DexFile(getPackageCodePath());
List<String> classes = new ArrayList<String>();
Enumeration<String> en = df.entries();
while(en.hasMoreElements()){
String e = en.nextElement();
if(e.startsWith(pck)){
classes.add(e);
}
}
return classes;
}

/**
* 此处考虑到强引用关系并未使用{@link Context#getPackageCodePath()}
* @return
*/
private String getPackageCodePath(){
URL url = ClassScanner.class.getResource("scan");
String path = url.getPath();
return path.substring(0, path.indexOf("!")).replace("file:", "");
}
}


本文参考以下资料

主要对查找资源方法ClassLoader.getResource(name)进行了说明

https://github.com/hunterhacker/jdom/wiki/JDOM2—Android-Issue—getSystemResource

Android平台实现包下类扫描的一些问答

http://stackoverflow.com/questions/15446036/find-all-classes-in-a-package-in-android
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: