我已经成功从android模拟器中提取了类文件,并将它们替换为我的android.jar文件,该文件驻留在我的\ platforms \ android-21 \ android.jar中,我仍然无法访问隐藏的方法。我以前使用过android 19,但要保持我的版本更新。我知道我可以使用反射,但在Android Studio中原生支持它会更容易。
使用JD-GUI我可以确认类和方法在android.jar文件中,但Android Studio“无法解析符号”。我在这里很重要。谢谢大家。
编辑:我确实有repo设置,所以如果从源代码编译android.jar文件是可能的,我不介意这样做。答案 0 :(得分:1)
档案>使高速缓存无效并重新启动>无效并重新启动
我知道一些奇怪的事情。我知道罐子里有方法,我知道它与Studio有关。在这里它缓存方法:)
我在第一行发布的内容修复了它!很高兴!希望别人受益!
答案 1 :(得分:1)
dependencies {
provided files('systemlibs/android.jar')
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
}
答案 2 :(得分:0)
你不必替换\ platforms \ android-21 \ android.jar 它会破坏SDK,你可能不会将这些更改提交给git。
以下方式可能更容易:
请参阅How do I build the Android SDK with hidden and internal APIs available?并获取framework_all.jar
将framework_all.jar放在除项目中app之外的system_libraries中。
更改app / build.gradle,如
dependencies {
compile fileTree(dir: 'libs', include: ['.jar'])
provided fileTree(dir: '../system_libraries', include: ['.jar'])
}
AS会提供“Gradle文件自......立即同步后更改”等提示,点击立即同步。
转到项目视图,您将在外部库中看到platform_all.jar。
每次更改system_libraries下的任何.jar时,您需要在app / build.gradle中进行一些更改并重新同步它。
答案 3 :(得分:0)
这里有一个替代方案,它不需要构建整个android SDK JAR或修改你的android SDK。如果你有一个JAR包含一些@hide
android SDK类和/或方法,你可以将这个hunk添加到你的标准android项目build.gradle文件中:
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xbootclasspath/p:<FULL_PATH_TO_CUSTOM_ANDROID_API>.jar"
}
}
}
这会将您的JAR添加到bootclasspath,其中包含所选SDK中的android.jar。编译时,java编译器更喜欢使用前置bootclasspath中的类,从而覆盖SDK中的android.jar。
请参阅http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html
缺点是IntelliJ / Android Studio似乎并没有在更高级别理解这一点,因此方法在编辑器中显示为红色,但构建工作正常。实际上,您可以将其与provided
解决方案结合起来,至少可以获得在编辑器中显示为有效的其他类,但IDE仍然不知道公开的@hide
方法。
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'], 'exclude': ['<PATH_TO_CUSTOM_ANDROID_API>.jar'])
provided files('libs/<PATH_TO_CUSTOM_ANDROID_API>.jar')
}
我还没玩过足够长的时间来找到如何在compilerArgs中引用相对路径,但它应该很容易。
答案 4 :(得分:0)
有一阵子,我使用了Xbootclasspath
技巧,但是Android Studio并不喜欢它(突出显示被破坏了),如果您尝试访问在SDK中已更改的隐藏API,则根本无法使用级别(这些API是隐藏的,因此不稳定)。
最终,我找到了一个解决方案,其中涉及创建用于我的Android项目的纯Java库。我称这个技巧为“无平台隐藏”(又名P-U)。主要的烦恼是存在更多样板代码,并且库结构很复杂。
如果您需要支持两个级别(假设API级别为25和更低,API级别为26和更高),那么您将需要5个Java库。 “存根”库包含从AOSP复制的Android平台代码,但像SDK中的android.jar这样,存根都被隐藏了,但是带有要公开的隐藏方法。
“包装”库使用存根库并公开具有唯一名称的方法/类。 P-U库根据检测到的Build.SDK_INT
的SDK级别选择适当的包装库。
外观上看起来像这样:
+---------+ +----------+
+--api-->+ wrap-25 +--compile-only-->+ stubs-25 +--+
+-------+ | +---------+ +----------+ | +---------+
| +---+ +-->+ |
| P-U | | android |
| +---+ +-->+ |
+-------+ | +---------+ +----------+ | +---------+
+--api-->+ wrap-26 +--compile-only-->+ stubs-26 +--+
+---------+ +----------+
设置Java库需要创建一个共享的gradle文件,如下所示:
platform-shared.gradle:
// All the platform-* projects apply this gradle file
apply plugin: 'java'
apply plugin: 'java-library'
sourceCompatibility = 1.8
apply from: file("${androidBuild}/versions.gradle")
// ANDROID_HOME can override ANDROID_SDK_ROOT
// see https://developer.android.com/studio/command-line/variables
def androidHome = System.getenv('ANDROID_HOME')
def androidSdkRoot = System.getenv('ANDROID_SDK_ROOT')
if (androidHome?.trim() && new File(androidHome).canRead()) {
androidSdkRoot = androidHome
}
if (!androidSdkRoot?.trim() || !new File(androidSdkRoot).canRead()) {
def props = new Properties()
def file = new File("${rootDir}/local.properties")
if (file.exists()) {
file.withInputStream { props.load(it) }
if (props.getProperty("sdk.dir")) {
androidSdkRoot = props.getProperty("sdk.dir")
}
}
else {
throw new GradleException('Android SDK root not usable')
}
}
repositories {
// Need an Android SDK jar to compile against even though this is a pure java project
repositories {
flatDir {
dirs "${androidSdkRoot}/platforms/android-${COMPILE_SDK_VERSION}"
}
}
mavenCentral()
}
// Make CI happy by implementing these tasks
task assembleRelease {
dependsOn 'jar'
}
task assembleDebug {
dependsOn 'jar'
}
task assembleAndroidTest {
// Ignored
}
task lintRelease {
// Ignored
}
task lintDebug {
// Ignored
}
task testReleaseUnitTest {
// Ignored
}
task testDebugUnitTest {
// Ignored
}
然后,您将需要为每个库添加gradle文件(不显示26,它看起来与25相同)。根据需要添加更多级别。
存根25.gradle:
apply from: file("../platform-shared.gradle")
dependencies {
api name: "android"
}
包装25.gradle:
apply from: file("../platform-shared.gradle")
dependencies {
compileOnly project(':platform-stubs-25')
}
platform-unhidden.gradle:
apply from: file("../platform-shared.gradle")
dependencies {
compileOnly project(':platform-stubs-25')
compileOnly name: "android"
api project(':platform-wrap-25')
api project(':platform-wrap-26')
}