我有一个 flutter 应用程序,它会生成很多隐藏的 API 警告:
Accessing hidden method Landroid/view/accessibility/AccessibilityNodeInfo;->getSourceNodeId()J (greylist,test-api, reflection, allowed)
Accessing hidden method Landroid/view/accessibility/AccessibilityRecord;->getSourceNodeId()J (greylist, reflection, allowed)
Accessing hidden field Landroid/view/accessibility/AccessibilityNodeInfo;->mChildNodeIds:Landroid/util/LongArray; (greylist, reflection, allowed)
Accessing hidden method Landroid/util/LongArray;->get(I)J (greylist, reflection, allowed)
...
Accessing hidden method Landroid/database/sqlite/SQLiteDatabase;-><clinit>()V (blacklist, linking, denied)
Accessing hidden field Landroid/database/sqlite/SQLiteDatabase;->DEBUG_CLOSE_IDLE_CONNECTIONS:Z (greylist-max-o, linking, denied)
Accessing hidden field Landroid/database/sqlite/SQLiteDatabase;->sActiveDatabases:Ljava/util/WeakHashMap; (greylist-max-o, linking, denied)
Accessing hidden field Landroid/database/sqlite/SQLiteDatabase;->CONFLICT_VALUES:[Ljava/lang/String; (greylist, linking, allowed)
Run Code Online (Sandbox Code Playgroud)
等等。我还没有编写任何代码来使用 Android 的SQLiteDatabase或AccessibilityNodeInfo,但这没有提供有关哪段代码正在调用这些隐藏方法的任何信息。它可能在 Flutter 中,或者我拥有的几个插件之一中。除了破坏我的代码来删除这些插件之外,我可以做些什么来找出调用这些插件的代码吗?即获取堆栈跟踪。
Android 是否可以选择在隐藏字段访问时崩溃,而不仅仅是记录它们,或者类似的东西?
啊哈,感谢 Mark Keen 的链接,我能够Application为我的 Flutter 应用程序创建一个自定义项,用于记录严格模式违规的堆栈跟踪。创建一个MainApplication.ktKotlin 文件,如下所示:
package com.yourdomain.flutter_app
import android.app.Application
import android.os.StrictMode
import android.os.StrictMode.OnVmViolationListener
import android.os.StrictMode.VmPolicy
import android.os.strictmode.Violation
import android.util.Log
import io.flutter.view.FlutterMain
import java.io.PrintWriter
import java.io.StringWriter
import java.util.concurrent.Executor
class CurrentThreadExecutor : Executor {
override fun execute(r: Runnable) {
r.run()
}
}
class StacktraceLogger : OnVmViolationListener {
override fun onVmViolation(v: Violation) {
val sw = StringWriter()
val pw = PrintWriter(sw)
v.printStackTrace(pw)
Log.e("STRICTMODE", sw.toString())
}
}
class MainApplication : Application() {
override fun onCreate() {
super.onCreate()
val policy = VmPolicy.Builder()
.detectAll()
.detectNonSdkApiUsage()
.penaltyListener(CurrentThreadExecutor(), StacktraceLogger())
.build()
StrictMode.setVmPolicy(policy)
FlutterMain.startInitialization(applicationContext)
}
}
Run Code Online (Sandbox Code Playgroud)
然后将你的指向AndroidManifest.xml它:
<application
android:name="com.yourdomain.flutter_app.MainApplication"
Run Code Online (Sandbox Code Playgroud)
然后,当您运行它时,您应该看到堆栈跟踪。在这种情况下,AccessibilityNodeInfo问题似乎确实是 Flutter 问题:
2021-02-20 12:43:11.986 3291-3291/uk.co.timhutt.flutter_app E/STRICTMODE: android.os.strictmode.NonSdkApiUsedViolation: Landroid/view/accessibility/AccessibilityNodeInfo;->getSourceNodeId()J
at android.os.StrictMode.lambda$static$1(StrictMode.java:416)
at android.os.-$$Lambda$StrictMode$lu9ekkHJ2HMz0jd3F8K8MnhenxQ.accept(Unknown Source:2)
at java.lang.Class.getDeclaredMethodInternal(Native Method)
at java.lang.Class.getPublicMethodRecursive(Class.java:2079)
at java.lang.Class.getMethod(Class.java:2066)
at java.lang.Class.getMethod(Class.java:1693)
at io.flutter.view.AccessibilityViewEmbedder$ReflectionAccessors.<init>(AccessibilityViewEmbedder.java:446)
at io.flutter.view.AccessibilityViewEmbedder$ReflectionAccessors.<init>(AccessibilityViewEmbedder.java:429)
at io.flutter.view.AccessibilityViewEmbedder.<init>(AccessibilityViewEmbedder.java:70)
at io.flutter.view.AccessibilityBridge.<init>(AccessibilityBridge.java:346)
at io.flutter.embedding.android.FlutterView.attachToFlutterEngine(FlutterView.java:919)
at io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.onCreateView(FlutterActivityAndFragmentDelegate.java:294)
at io.flutter.embedding.android.FlutterActivity.createFlutterView(FlutterActivity.java:520)
at io.flutter.embedding.android.FlutterActivity.onCreate(FlutterActivity.java:414)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3404)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7660)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Run Code Online (Sandbox Code Playgroud)
奇怪的是,它仍然没有打印任何 SQLite 错误的堆栈跟踪,但我注意到第一个错误是“反射”,而那些是“链接”。我正在链接一个 Rust 库,该库使用 SQLite 的捆绑副本 - 使用以下依赖项:
rusqlite = { version = "0.24.2", features = ["bundled"] }
Run Code Online (Sandbox Code Playgroud)
然后将其加载到 Dart 中:
final DynamicLibrary mapRenderNative = Platform.isAndroid
? DynamicLibrary.open("libmap_render.so")
: DynamicLibrary.process();
Run Code Online (Sandbox Code Playgroud)
当我评论该行并运行wgradle clean(看起来有必要)时,错误消失了!卧槽?Android 似乎会拦截dlopen()并检查您是否链接到任何禁止的符号。
但真正奇怪的是 mylibmap_render.so 不链接SQLite(因为它静态链接到其中):
>llvm-readelf -d target\aarch64-linux-android\debug\libmap_render.so
Dynamic section at offset 0x52768 contains 23 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libdl.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so]
0x000000000000001e (FLAGS) BIND_NOW
0x000000006ffffffb (FLAGS_1) NOW
0x0000000000000007 (RELA) 0x988
0x0000000000000008 (RELASZ) 9768 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffff9 (RELACOUNT) 405
0x0000000000000017 (JMPREL) 0x2fb0
0x0000000000000002 (PLTRELSZ) 888 (bytes)
0x0000000000000003 (PLTGOT) 0x54940
0x0000000000000014 (PLTREL) RELA
0x0000000000000006 (SYMTAB) 0x308
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000005 (STRTAB) 0x79c
0x000000000000000a (STRSZ) 491 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x778
0x000000000000001a (FINI_ARRAY) 0x54758
0x000000000000001c (FINI_ARRAYSZ) 16 (bytes)
0x000000006ffffff0 (VERSYM) 0x6e0
0x000000006ffffffe (VERNEED) 0x734
0x000000006fffffff (VERNEEDNUM) 2
0x0000000000000000 (NULL) 0x0
Run Code Online (Sandbox Code Playgroud)
我也无法在符号表、重定位等中找到任何 SQLite 符号。所以我根本不知道 Android 在做什么。它真的扫描二进制文件吗?
我想我会为此提出一个新问题。
| 归档时间: |
|
| 查看次数: |
14615 次 |
| 最近记录: |