两种方法 :1. 反射 2. 狸猫换太子 把系统的class.jar 导入项目的libs文件夹 使用该jar包
1.反射
获取u盘路径 public static String getUDiskPath() { StorageManager mStorageManager = getContext().getSystemService(StorageManager.class); if (mStorageManager != null) { try { Class storeManagerClazz = null; try { storeManagerClazz = Class.forName("android.os.storage.StorageManager"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Method getVolumesMethod = storeManagerClazz.getMethod("getVolumes"); List<?> volumeInfos = (List<?>) getVolumesMethod.invoke(mStorageManager); Class volumeInfoClazz = Class.forName("android.os.storage.VolumeInfo"); Method getFsUuidMethod = volumeInfoClazz.getMethod("getFsUuid"); Field pathField = volumeInfoClazz.getDeclaredField("path"); if(volumeInfos != null){ for(Object volumeInfo:volumeInfos){ String uuid = (String)getFsUuidMethod.invoke(volumeInfo); if(uuid != null){ String pathString = (String)pathField.get(volumeInfo); return pathString; } } } } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return null; }
2.替换jar包
1.获取Android源码并进行编译。
2..编译完毕后,取出out\target\common\obj\JAVA_LIBRARIES\framework_intermediates路径下的classes.jar
3.将classes.jar重命名为framework.jar并添加到Android Studio项目的libs目录下。
4.在build.gradle中的dependencies中,添加:
compileOnly files('libs/framework.jar')
5.在build.gradle中的Android节点设置编译参数 可以解决编译时找不到符号的错误
gradle.projectsEvaluated { tasks.withType(JavaCompile) { Set<File> fileSet = options.bootstrapClasspath.getFiles() List<File> newFileList = new ArrayList<>(); //JAVA语法,可连续调用,输入参数建议为相对路径 newFileList.add(new File("libs/framework.jar")) //最后将原始参数添加 newFileList.addAll(fileSet) options.bootstrapClasspath = files( newFileList.toArray() ) } }
- 或者在工程的根目录build.gradle中找到allprojects,加入如下代码(新版本无效)
gradle.projectsEvaluated { tasks.withType(JavaCompile) { options.compilerArgs.add('-Xbootclasspath/p:app\\libs\\framework.jar') } }
allprojects { tasks.withType(JavaCompile) { options.compilerArgs.add('-Xbootclasspath/p:app\\libs\\framework.jar') } }
7.配置依赖优先级,否则Android studio默认引用配置的Android sdk进行编译,可以解决点击方法名,无法跳转的问题
def imlFile = file("\\..\\.idea\\modules\\app\\"+rootProject.name+'.'+projectDir.name+'.iml')
def imlFile = file("\\..\\.idea\\modules\\"+projectDir.name+"\\"+rootProject.name+'.'+projectDir.name+'.main.iml')
preBuild { doLast { //def imlFile = file(project.name + ".iml") //AndroidStudio 3.x 适用 //Android studio4.0的app.iml文件路径为项目/.idea/modules/app/app.iml。早期版本,app.iml文件在项目根目录下 //def imlFile = file("\\..\\.idea\\modules\\app\\app.iml") def imlFile = file("\\..\\.idea\\modules\\app\\DiagnoseDemoTest.app.main.iml" ) println 'path=' + projectDir.absolutePath // println 'Change ' + project.name + '.iml order' try { def parsedXml = (new XmlParser()).parse(imlFile) def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' } parsedXml.component[1].remove(jdkNode) println 'api =' + android.compileSdkVersion.substring("android-".length()) def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform" new groovy.util.Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK']) groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile)) } catch (FileNotFoundException e) { // nop, iml not found e.printStackTrace(); } } }
这个 task 在编译之前, 自动更改.idea/modules/app/DiagnoseDemoTest.app.iml,将下面代码会移动最后,才能在编译时使用我们引入的 framework.jar。
<orderEntry type="jdk" jdkName="Android API 30 Platform" jdkType="Android SDK" />