Closed lizhangqu closed 6 years ago
我测试了这个方法,确实报 NoSuchMethodException,但是没有任何诸如:
Accessing hidden method XXX
之类的提示,我怀疑是不是真的没有这个方法。
另外,对于方法 public void android.content.pm.ApplicationInfo.setHiddenApiEnforcementPolicy(int)
,这是在深灰名单中的。我做了如下测试:
结合 1、3,可以看出:深灰名单在 target api >= 28的时候表现为黑名单,< 28为浅灰名单。再对比1、2,3、4,说明本库是可以正常工作的。
之所以怀疑源码不是同步的,是因为我发现另外一个方法:android.content.pm.PackageParser$Package.collectCertificates
,这个方法在 android-p-preview-3 分枝上,源码的签名为:
android.content.pm.PackageParser collectCertificates(android.content.pm.PackageParser$Package, int)
但是android p的模拟器上,并无这个方法,而是这个:
android.content.pm.PackageParser collectCertificates(android.content.pm.PackageParser$Package, boolean)
所以目前判断应该是rom上确实无此方法,源码同步上存在问题
这个也一样,AOSP源码上有,但是报NoSuchMethodException
AssetManager.class.getDeclaredMethod("addAssetPaths", String[].class);
AssetManager 这个类已经很久没有动过了,难道是黑名单有特殊的处理方式?但是 https://android.googlesource.com/platform/frameworks/base/+/android-p-preview-3/config/ 也没有任何黑名单列表,真是奇怪了。。
try {
Class<?> aClass = Class.forName("dalvik.system.VMRuntime");
Method setHiddenApiExemptions = aClass.getDeclaredMethod("setHiddenApiExemptions", String.class);
setHiddenApiExemptions.setAccessible(true);
} catch (Exception e) {
e.printStackTrace();
}
java.lang.NoSuchMethodException: setHiddenApiExemptions [class java.lang.String]
AssetManager深灰名单
Landroid/content/res/AssetManager;-><init>(Z)V
Landroid/content/res/AssetManager;->DEBUG_REFS:Z
Landroid/content/res/AssetManager;->STYLE_ASSET_COOKIE:I
Landroid/content/res/AssetManager;->STYLE_CHANGING_CONFIGURATIONS:I
Landroid/content/res/AssetManager;->STYLE_DATA:I
Landroid/content/res/AssetManager;->STYLE_DENSITY:I
Landroid/content/res/AssetManager;->STYLE_NUM_ENTRIES:I
Landroid/content/res/AssetManager;->STYLE_RESOURCE_ID:I
Landroid/content/res/AssetManager;->STYLE_TYPE:I
Landroid/content/res/AssetManager;->TAG:Ljava/lang/String;
Landroid/content/res/AssetManager;->addAssetPathInternal(Ljava/lang/String;Z)I
Landroid/content/res/AssetManager;->addAssetPathNative(Ljava/lang/String;Z)I
Landroid/content/res/AssetManager;->addAssetPaths([Ljava/lang/String;)[I
Landroid/content/res/AssetManager;->addOverlayPathNative(Ljava/lang/String;)I
Landroid/content/res/AssetManager;->applyStyle(JIIJ[IIJJ)V
Landroid/content/res/AssetManager;->applyThemeStyle(JIZ)V
Landroid/content/res/AssetManager;->clearTheme(J)V
Landroid/content/res/AssetManager;->copyTheme(JJ)V
Landroid/content/res/AssetManager;->decRefsLocked(J)V
Landroid/content/res/AssetManager;->deleteTheme(J)V
Landroid/content/res/AssetManager;->destroy()V
Landroid/content/res/AssetManager;->destroyAsset(J)V
Landroid/content/res/AssetManager;->dumpTheme(JILjava/lang/String;Ljava/lang/String;)V
Landroid/content/res/AssetManager;->ensureStringBlocks()[Landroid/content/res/StringBlock;
Landroid/content/res/AssetManager;->ensureSystemAssets()V
Landroid/content/res/AssetManager;->getArrayIntResource(I)[I
Landroid/content/res/AssetManager;->getArraySize(I)I
Landroid/content/res/AssetManager;->getArrayStringInfo(I)[I
Landroid/content/res/AssetManager;->getArrayStringResource(I)[Ljava/lang/String;
Landroid/content/res/AssetManager;->getAssetAllocations()Ljava/lang/String;
Landroid/content/res/AssetManager;->getAssetLength(J)J
Landroid/content/res/AssetManager;->getAssetRemainingLength(J)J
Landroid/content/res/AssetManager;->getCookieName(I)Ljava/lang/String;
Landroid/content/res/AssetManager;->getNativeStringBlock(I)J
Landroid/content/res/AssetManager;->getNonSystemLocales()[Ljava/lang/String;
Landroid/content/res/AssetManager;->getPooledStringForCookie(II)Ljava/lang/CharSequence;
Landroid/content/res/AssetManager;->getResourceStringArray(I)[Ljava/lang/String;
Landroid/content/res/AssetManager;->getResourceTextArray(I)[Ljava/lang/CharSequence;
Landroid/content/res/AssetManager;->getSizeConfigurations()[Landroid/content/res/Configuration;
Landroid/content/res/AssetManager;->getStringBlockCount()I
Landroid/content/res/AssetManager;->getStyleAttributes(I)[I
Landroid/content/res/AssetManager;->getThemeChangingConfigurations(J)I
Landroid/content/res/AssetManager;->getThemeValue(JILandroid/util/TypedValue;Z)Z
Landroid/content/res/AssetManager;->incRefsLocked(J)V
Landroid/content/res/AssetManager;->init(Z)V
Landroid/content/res/AssetManager;->loadResourceBagValue(IILandroid/util/TypedValue;Z)I
Landroid/content/res/AssetManager;->loadResourceValue(ISLandroid/util/TypedValue;Z)I
Landroid/content/res/AssetManager;->loadThemeAttributeValue(JILandroid/util/TypedValue;Z)I
Landroid/content/res/AssetManager;->localLOGV:Z
Landroid/content/res/AssetManager;->mNumRefs:I
Landroid/content/res/AssetManager;->mOffsets:[J
Landroid/content/res/AssetManager;->mOpen:Z
Landroid/content/res/AssetManager;->mRefStacks:Ljava/util/HashMap;
Landroid/content/res/AssetManager;->mStringBlocks:[Landroid/content/res/StringBlock;
Landroid/content/res/AssetManager;->mValue:Landroid/util/TypedValue;
Landroid/content/res/AssetManager;->makeStringBlocks([Landroid/content/res/StringBlock;)V
Landroid/content/res/AssetManager;->newTheme()J
Landroid/content/res/AssetManager;->openAsset(Ljava/lang/String;I)J
Landroid/content/res/AssetManager;->openAssetFd(Ljava/lang/String;[J)Landroid/os/ParcelFileDescriptor;
Landroid/content/res/AssetManager;->openNonAssetFdNative(ILjava/lang/String;[J)Landroid/os/ParcelFileDescriptor;
Landroid/content/res/AssetManager;->openNonAssetNative(ILjava/lang/String;I)J
Landroid/content/res/AssetManager;->openXmlAssetNative(ILjava/lang/String;)J
Landroid/content/res/AssetManager;->openXmlBlockAsset(ILjava/lang/String;)Landroid/content/res/XmlBlock;
Landroid/content/res/AssetManager;->openXmlBlockAsset(Ljava/lang/String;)Landroid/content/res/XmlBlock;
Landroid/content/res/AssetManager;->readAsset(J[BII)I
Landroid/content/res/AssetManager;->readAssetChar(J)I
Landroid/content/res/AssetManager;->releaseTheme(J)V
Landroid/content/res/AssetManager;->retrieveArray(I[I)I
Landroid/content/res/AssetManager;->retrieveAttributes(J[I[I[I)Z
Landroid/content/res/AssetManager;->sSync:Ljava/lang/Object;
Landroid/content/res/AssetManager;->seekAsset(JJI)J
Landroid/content/res/AssetManager;->xmlBlockGone(I)V
若您想在 adb logcat 中显示 API 访问信息,您可通过以下命令更改 API 执行策略:
这个都不行。
adb shell oatdump --oat-file=/system/framework/arm/boot-framework.oat --method-filter=addAssetPath
OAT FILE STATS:
Dumping cumulative use of 273 accounted bytes
Code = 132 (48% of total)
QuickMethodHeader = 72 (26% of total)
CodeInfoEncoding = 38 (14% of total)
CodeInfoLocationCatalog = 8 ( 3% of total)
CodeInfoDexRegisterMap = 8 ( 3% of total)
CodeInfoStackMasks = 0 ( 0% of total)
CodeInfoRegisterMasks = 5 ( 2% of total)
CodeInfoInvokeInfo = 0 ( 0% of total)
CodeInfoStackMap = 10 ( 4% of total)
StackMapNativePc = 4 (43% of stack map)
StackMapDexPcEncoding = 1 (14% of stack map)
StackMapDexRegisterMap = 2 (21% of stack map)
StackMapInlineInfoIndex = 0 ( 0% of stack map)
StackMapRegisterMaskIndex = 1 (14% of stack map)
StackMapStackMaskIndex = 0 ( 7% of stack map)
CodeInfoInlineInfo = 0 ( 0% of total)
InlineInfoMethodIndexIdx = 0 (nan% of inline info)
InlineInfoDexPc = 1 (inf% of inline info)
InlineInfoExtraData = 0 (nan% of inline info)
InlineInfoDexRegisterMap = 0 (nan% of inline info)
InlineInfoIsLast = 0 (nan% of inline info)
adb shell oatdump --oat-file=/system/framework/arm/boot-framework.oat --method-filter=addAssetPaths
Dumping cumulative use of 0 accounted bytes
AOSP代码中无android.content.res.ApkAssets类,但是dump出来,有android.content.res.ApkAssets类
15: int android.content.res.AssetManager.addAssetPathInternal(java.lang.String, boolean, boolean) (dex_method_idx=23261)
DEX CODE:
0x0000: 1b00 a52f 0100 | const-string/jumbo v0, "path" // string@77733
0x0003: 7120 b8f6 0800 | invoke-static {v8, v0}, java.lang.Object com.android.internal.util.Preconditions.checkNotNull(java.lang.Object, java.lang.Object) // method@63160
0x0006: 1d07 | monitor-enter v7
0x0007: 7010 e65a 0700 | invoke-direct {v7}, void android.content.res.AssetManager.ensureOpenLocked() // method@23270
0x000a: e570 0800 | iget-object-quick v0, v7, // offset@8
0x000c: 2100 | array-length v0, v0
0x000d: 1201 | const/4 v1, #+0
0x000e: 0112 | move v2, v1
0x000f: 3502 1700 | if-ge v2, v0, +23
0x0011: e573 0800 | iget-object-quick v3, v7, // offset@8
0x0013: 4603 0302 | aget-object v3, v3, v2
0x0015: e910 0b00 0300 | invoke-virtual-quick {v3}, // vtable@11
0x0018: 0c03 | move-result-object v3
0x0019: e920 0100 8300 | invoke-virtual-quick {v3, v8}, // vtable@1
0x001c: 0a03 | move-result v3
0x001d: 3803 0600 | if-eqz v3, +6
0x001f: d801 0201 | add-int/lit8 v1, v2, #+1
0x0021: 1e07 | monitor-exit v7
0x0022: 0f01 | return v1
0x0023: d802 0201 | add-int/lit8 v2, v2, #+1
0x0025: 28ea | goto -22
0x0026: 1212 | const/4 v2, #+1
0x0027: 3809 2c00 | if-eqz v9, +44
0x0029: 2203 8e1b | new-instance v3, java.lang.StringBuilder // type@TypeIndex[7054]
0x002b: 7010 3af9 0300 | invoke-direct {v3}, void java.lang.StringBuilder.<init>() // method@63802
0x002e: 1a04 690b | const-string v4, "/data/resource-cache/" // string@2921
0x0030: e920 4b00 4300 | invoke-virtual-quick {v3, v4}, // vtable@75
0x0033: e920 3700 2800 | invoke-virtual-quick {v8, v2}, // vtable@55
0x0036: 0c04 | move-result-object v4
0x0037: 1305 2f00 | const/16 v5, #+47
0x0039: 1306 4000 | const/16 v6, #+64
0x003b: e930 2e00 5406 | invoke-virtual-quick {v4, v5, v6}, // vtable@46
0x003e: 0c04 | move-result-object v4
0x003f: e920 4b00 4300 | invoke-virtual-quick {v3, v4}, // vtable@75
0x0042: 1a04 0f0d | const-string v4, "@idmap" // string@3343
0x0044: e920 4b00 4300 | invoke-virtual-quick {v3, v4}, // vtable@75
0x0047: e910 0700 0300 | invoke-virtual-quick {v3}, // vtable@7
0x004a: 0c03 | move-result-object v3
0x004b: 7120 8e5a 1300 | invoke-static {v3, v1}, android.content.res.ApkAssets android.content.res.ApkAssets.loadOverlayFromPath(java.lang.String, boolean) // method@23182
0x004e: 0c04 | move-result-object v4
0x004f: 0741 | move-object v1, v4
0x0050: 2808 | goto +8
0x0051: 0d02 | move-exception v2
0x0052: 2827 | goto +39
0x0053: 7130 8d5a 180a | invoke-static {v8, v1, v10}, android.content.res.ApkAssets android.content.res.ApkAssets.loadFromPath(java.lang.String, boolean, boolean) // method@23181
0x0056: 0c03 | move-result-object v3
0x0057: 0731 | move-object v1, v3
0x0058: 0000 | nop
0x0059: 0000 | nop
0x005a: e573 0800 | iget-object-quick v3, v7, // offset@8
0x005c: d804 0001 | add-int/lit8 v4, v0, #+1
0x005e: 7120 f2fa 4300 | invoke-static {v3, v4}, java.lang.Object[] java.util.Arrays.copyOf(java.lang.Object[], int) // method@64242
0x0061: 0c03 | move-result-object v3
0x0062: 1f03 841d | check-cast v3, android.content.res.ApkAssets[] // type@TypeIndex[7556]
0x0064: e873 0800 | iput-object-quick v3, v7, // offset@8
0x0066: e573 0800 | iget-object-quick v3, v7, // offset@8
0x0068: 4d01 0300 | aput-object v1, v3, v0
0x006a: e473 1800 | iget-wide-quick v3, v7, thing@24
0x006c: e575 0800 | iget-object-quick v5, v7, // offset@8
0x006e: 7140 295b 4325 | invoke-static {v3, v4, v5, v2}, void android.content.res.AssetManager.nativeSetApkAssets(long, android.content.res.ApkAssets[], boolean) // method@23337
0x0071: 12f2 | const/4 v2, #-1
0x0072: 7020 045b 2700 | invoke-direct {v7, v2}, void android.content.res.AssetManager.invalidateCachesLocked(int) // method@23300
0x0075: d802 0001 | add-int/lit8 v2, v0, #+1
0x0077: 1e07 | monitor-exit v7
0x0078: 0f02 | return v2
0x0079: 0000 | nop
0x007a: 1e07 | monitor-exit v7
0x007b: 0f01 | return v1
0x007c: 0d00 | move-exception v0
0x007d: 1e07 | monitor-exit v7
0x007e: 2700 | throw v0
OatMethodOffsets (offset=0x00000000)
code_offset: 0x00000000
OatQuickMethodHeader (offset=0x00000000)
vmap_table: (offset=0x00000000)
QuickMethodFrameInfo
frame_size_in_bytes: 0
core_spill_mask: 0x00000000
fp_spill_mask: 0x00000000
vr_stack_locations:
locals: v0[sp + #4294967264] v1[sp + #4294967268] v2[sp + #4294967272] v3[sp + #4294967276] v4[sp + #4294967280] v5[sp + #4294967284] v6[sp + #4294967288]
ins: v7[sp + #4] v8[sp + #8] v9[sp + #12] v10[sp + #16]
method*: v11[sp + #0]
outs: v0[sp + #4] v1[sp + #8] v2[sp + #12] v3[sp + #16]
CODE: (code_offset=0x00000000 size_offset=0x00000000 size=0)
NO CODE!
71: int android.content.res.AssetManager.addAssetPath(java.lang.String) (dex_method_idx=23259)
DEX CODE:
0x0000: 1200 | const/4 v0, #+0
0x0001: 7040 dd5a 2100 | invoke-direct {v1, v2, v0, v0}, int android.content.res.AssetManager.addAssetPathInternal(java.lang.String, boolean, boolean) // method@23261
0x0004: 0a00 | move-result v0
0x0005: 0f00 | return v0
OatMethodOffsets (offset=0x0003543c)
code_offset: 0x0063d081
OatQuickMethodHeader (offset=0x0063d068)
vmap_table: (offset=0x005abb2c)
Optimized CodeInfo (number_of_dex_registers=3, number_of_stack_maps=3)
StackMapEncoding (native_pc_bit_offset=0, dex_pc_bit_offset=6, dex_register_map_bit_offset=8, inline_info_bit_offset=11, register_mask_bit_offset=11, stack_mask_index_bit_offset=13, total_bit_size=14)
DexRegisterLocationCatalog (number_of_entries=4, size_in_bytes=4)
entry 0: in register (5)
entry 1: in register (6)
entry 2: in register (1)
entry 3: in register (2)
QuickMethodFrameInfo
frame_size_in_bytes: 32
core_spill_mask: 0x00004060 (r5, r6, r14)
fp_spill_mask: 0x00000000
vr_stack_locations:
locals: v0[sp + #12]
ins: v1[sp + #36] v2[sp + #40]
method*: v3[sp + #0]
outs: v0[sp + #4] v1[sp + #8] v2[sp + #12] v3[sp + #16]
CODE: (code_offset=0x0063d081 size_offset=0x0063d07c size=66)...
0x0063d080: f5ad5400 sub r4, sp, #8192
0x0063d084: 6824 ldr r4, [r4]
StackMap [native_pc=0x63d087] [entry_size=0xe bits] (dex_pc=0x0, native_pc_offset=0x6, dex_register_map_offset=0xffffffff, inline_info_offset=0xffffffff, register_mask=0x0, stack_mask=0b)
0x0063d086: b560 push {r5,r6,lr}
0x0063d088: b085 sub sp, #20
0x0063d08a: 9000 str r0, [sp]
0x0063d08c: f8b9c000 ldrh ip, [tr] ; state_and_flags
0x0063d090: f1bc0f00 cmp ip, #0
0x0063d094: f0408011 bne.w 0x0063d0ba
0x0063d098: 460d mov r5, r1
0x0063d09a: 4616 mov r6, r2
0x0063d09c: f04f0c00 mov ip, #0
0x0063d0a0: f8cdc010 str ip, [sp, #16]
0x0063d0a4: 2300 movs r3, #0
0x0063d0a6: f64730ba mov r0, #31674
0x0063d0aa: f6cf607f movt r0, #65151
0x0063d0ae: 4478 add r0, pc
0x0063d0b0: f8d0e018 ldr lr, [r0, #24]
0x0063d0b4: 47f0 blx lr
StackMap [native_pc=0x63d0b7] [entry_size=0xe bits] (dex_pc=0x1, native_pc_offset=0x36, dex_register_map_offset=0x0, inline_info_offset=0xffffffff, register_mask=0x60, stack_mask=0b)
v1: in register (5) [entry 0]
v2: in register (6) [entry 1]
0x0063d0b6: b005 add sp, #20
0x0063d0b8: bd60 pop {r5,r6,pc}
0x0063d0ba: f8d9e2c0 ldr lr, [tr, #704] ; pTestSuspend
0x0063d0be: 47f0 blx lr
StackMap [native_pc=0x63d0c1] [entry_size=0xe bits] (dex_pc=0x0, native_pc_offset=0x40, dex_register_map_offset=0x2, inline_info_offset=0xffffffff, register_mask=0x6, stack_mask=0b)
v1: in register (1) [entry 2]
v2: in register (2) [entry 3]
0x0063d0c0: e7ea b 0x0063d098
72: int android.content.res.AssetManager.addAssetPathAsSharedLibrary(java.lang.String) (dex_method_idx=23260)
DEX CODE:
0x0000: 1200 | const/4 v0, #+0
0x0001: 1211 | const/4 v1, #+1
0x0002: 7040 dd5a 3210 | invoke-direct {v2, v3, v0, v1}, int android.content.res.AssetManager.addAssetPathInternal(java.lang.String, boolean, boolean) // method@23261
0x0005: 0a00 | move-result v0
0x0006: 0f00 | return v0
OatMethodOffsets (offset=0x00035440)
code_offset: 0x0063d0e1
OatQuickMethodHeader (offset=0x0063d0c8)
vmap_table: (offset=0x005abb69)
Optimized CodeInfo (number_of_dex_registers=4, number_of_stack_maps=3)
StackMapEncoding (native_pc_bit_offset=0, dex_pc_bit_offset=6, dex_register_map_bit_offset=8, inline_info_bit_offset=11, register_mask_bit_offset=11, stack_mask_index_bit_offset=13, total_bit_size=14)
DexRegisterLocationCatalog (number_of_entries=4, size_in_bytes=4)
entry 0: in register (5)
entry 1: in register (6)
entry 2: in register (1)
entry 3: in register (2)
QuickMethodFrameInfo
frame_size_in_bytes: 32
core_spill_mask: 0x00004060 (r5, r6, r14)
fp_spill_mask: 0x00000000
vr_stack_locations:
locals: v0[sp + #8] v1[sp + #12]
ins: v2[sp + #36] v3[sp + #40]
method*: v4[sp + #0]
outs: v0[sp + #4] v1[sp + #8] v2[sp + #12] v3[sp + #16]
CODE: (code_offset=0x0063d0e1 size_offset=0x0063d0dc size=66)...
0x0063d0e0: f5ad5400 sub r4, sp, #8192
0x0063d0e4: 6824 ldr r4, [r4]
StackMap [native_pc=0x63d0e7] [entry_size=0xe bits] (dex_pc=0x0, native_pc_offset=0x6, dex_register_map_offset=0xffffffff, inline_info_offset=0xffffffff, register_mask=0x0, stack_mask=0b)
0x0063d0e6: b560 push {r5,r6,lr}
0x0063d0e8: b085 sub sp, #20
0x0063d0ea: 9000 str r0, [sp]
0x0063d0ec: f8b9c000 ldrh ip, [tr] ; state_and_flags
0x0063d0f0: f1bc0f00 cmp ip, #0
0x0063d0f4: f0408011 bne.w 0x0063d11a
0x0063d0f8: 460d mov r5, r1
0x0063d0fa: 4616 mov r6, r2
0x0063d0fc: 2300 movs r3, #0
0x0063d0fe: f04f0c01 mov ip, #1
0x0063d102: f8cdc010 str ip, [sp, #16]
0x0063d106: f647305a mov r0, #31578
0x0063d10a: f6cf607f movt r0, #65151
0x0063d10e: 4478 add r0, pc
0x0063d110: f8d0e018 ldr lr, [r0, #24]
0x0063d114: 47f0 blx lr
StackMap [native_pc=0x63d117] [entry_size=0xe bits] (dex_pc=0x2, native_pc_offset=0x36, dex_register_map_offset=0x0, inline_info_offset=0xffffffff, register_mask=0x60, stack_mask=0b)
v2: in register (5) [entry 0]
v3: in register (6) [entry 1]
0x0063d116: b005 add sp, #20
0x0063d118: bd60 pop {r5,r6,pc}
0x0063d11a: f8d9e2c0 ldr lr, [tr, #704] ; pTestSuspend
0x0063d11e: 47f0 blx lr
StackMap [native_pc=0x63d121] [entry_size=0xe bits] (dex_pc=0x0, native_pc_offset=0x40, dex_register_map_offset=0x2, inline_info_offset=0xffffffff, register_mask=0x6, stack_mask=0b)
v2: in register (1) [entry 2]
v3: in register (2) [entry 3]
0x0063d120: e7ea b 0x0063d0f8
极大的问题还是出在AOSP源码上
Google 在耍什么花招。。😅
的确是源码的问题,今天发布的源码里面,并无此方法:https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/core/java/android/content/res/AssetManager.java 之前的一些疑点也得到了确认。
遇到类似问题:
activityManagerNative = Class.forName("android.app.ActivityManagerNative");
Object amn = activityManagerNative.getMethod("getDefault").invoke(activityManagerNative);
报错:
2023-08-17 17:10:41.238 17241-17241 .process.daemon com.crifan.keepaliveandroid W Accessing hidden method Landroid/app/ActivityManagerNative;->getDefault()Landroid/app/IActivityManager; (unsupported, reflection, allowed)
从之前FreeReflection
的
Reflection.unseal(base);
换成
https://github.com/whulzz1993/RePublic
具体步骤:
把其中的核心代码RePublic/src/main/cpp/RePublic.cpp
集成到自己的安卓项目中
System.loadLibrary("xxx")
触发,即可触发底层的JNI_OnLoad
的setApiBlacklistExemptions
,实现hidden api可用的效果
设备:Pixel DP3
源码:https://android.googlesource.com/platform/frameworks/base/+/android-p-preview-3/core/java/android/content/res/AssetManager.java#305
代码片段:
异常: