1. WebView 不能频繁调用 setHeight,否则会有频繁的 measure、layout 和 draw,会导致有闪烁感。如果需要对 WebView 进行动画,可以采用修改 margin 等方式(不修改长宽)。
  2. View.post 方法在不同的 android 版本下有不同的表现(有碎片化问题),需要注意和 runOnUiThread 表现并不一致。在老版本 android 系统上(API Level 24 前),View.post 是将任务加在 MainLooper 的末尾的,而新版本 android 的代码如下:
    public boolean post(Runnable action) {
    final AttachInfo attachInfo = mAttachInfo;
    if (attachInfo != null) {
    return attachInfo.mHandler.post(action);
    }
    // 如果 attachInfo 为 null,则加入 View 的 runQueue 中,而不是加入 MainLooper 的队列中
    // Postpone the runnable until we know on which thread it needs to run.
    // Assume that the runnable will be successfully placed after attach.
    getRunQueue().post(action);
    return true;
    }
  3. 如果声明的类或方法没有被调用,很有可能在编译时被优化裁剪掉。此时建议添加 @Keep 注解显式声明需要保留该方法或类。典型的例子就是 @JavascriptInterface 声明的方法。
  4. android.webkit.CookieManager#getInstance 的调用时机不能太早,要确保能够调用 AppGlobals.getInitialApplication(),否则可能会出现 crash:
    10-19 16:25:24.194 21971 21971 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.PackageManager android.app.Application.getPackageManager()' on a null object reference
    10-19 16:25:24.194 21971 21971 E AndroidRuntime: at android.webkit.WebViewFactory.isWebViewSupported(WebViewFactory.java:111)
    10-19 16:25:24.194 21971 21971 E AndroidRuntime: at android.webkit.WebViewFactory.getProvider(WebViewFactory.java:240)
    10-19 16:25:24.194 21971 21971 E AndroidRuntime: at android.webkit.CookieManager.getInstance(CookieManager.java:50)
    10-19 16:25:24.194 21971 21971 E AndroidRuntime: at com.example.streamingwebview.MyApplication.attachBaseContext(MyApplication.java:10)
    10-19 16:25:24.194 21971 21971 E AndroidRuntime: at android.app.Application.attach(Application.java:351)
    10-19 16:25:24.194 21971 21971 E AndroidRuntime: at android.app.Instrumentation.newApplication(Instrumentation.java:1159)
    10-19 16:25:24.194 21971 21971 E AndroidRuntime: at android.app.LoadedApk.makeApplication(LoadedApk.java:1260)
    10-19 16:25:24.194 21971 21971 E AndroidRuntime: ... 9 more
  5. Kotlin 调用 Java 方法时,会根据 Java 方法的签名推断返回值和参数的类型。这种推断基于 Kotlin 和 Java 类型系统的互操作性规则。以下是详细的类型推断规则和注意事项:
  • 基本类型的推断。Java 的基本数据类型(如 int, boolean, double)会自动映射为 Kotlin 的对应类型(如 Int, Boolean, Double)。
    // Java 方法
    public int add(int a, int b) {
    return a + b;
    }
    // Kotlin 调用
    val sum: Int = javaObj.add(5, 10) // 返回值被推断为 Int
    Java 的基本类型在 Kotlin 中不会为可空类型(Int? 等),因为基本类型本身不能为 null。
  • 可空类型的推断。Java 方法的返回值可能为 null,但 Java 本身并不强制标记。这时,Kotlin 默认将返回值视为平台类型(T!)
    // Java 方法
    public String getName() {
    return null; // 可能返回 null
    }
    // Kotlin 调用
    val name: String? = javaObj.name // 明确处理为可空类型
    val nameNonNull: String = javaObj.name // 如果你确信它不会为 null