@Test public void testCheckThread() { assumeTrue(WebViewFeature.isFeatureSupported(WebViewFeature.VISUAL_STATE_CALLBACK)); try { WebViewCompat.postVisualStateCallback(mWebViewOnUiThread.getWebViewOnCurrentThread(), 5, new WebViewCompat.VisualStateCallback() { @Override public void onComplete(long requestId) { } }); } catch (RuntimeException e) { return; } fail("Calling a WebViewCompat method on the wrong thread must cause a run-time exception"); }
@SuppressWarnings("NewApi") private static void checkThread(WebView webview) { if (BuildCompat.isAtLeastP()) { if (webview.getWebViewLooper() != Looper.myLooper()) { throw new RuntimeException("A WebView method was called on thread '" + Thread.currentThread().getName() + "'. " + "All WebView methods must be called on the same thread. " + "(Expected Looper " + webview.getWebViewLooper() + " called on " + Looper.myLooper() + ", FYI main Looper is " + Looper.getMainLooper() + ")"); } } else { try { Method checkThreadMethod = WebView.class.getDeclaredMethod("checkThread"); checkThreadMethod.setAccessible(true); checkThreadMethod.invoke(webview); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } }
WebViewCompat { @SuppressWarnings("NewApi") private static void checkThread(WebView webview) { if (BuildCompat.isAtLeastP()) { if (webview.getWebViewLooper() != Looper.myLooper()) { throw new RuntimeException("A WebView method was called on thread '" + Thread.currentThread().getName() + "'. " + "All WebView methods must be called on the same thread. " + "(Expected Looper " + webview.getWebViewLooper() + " called on " + Looper.myLooper() + ", FYI main Looper is " + Looper.getMainLooper() + ")"); } } else { try { Method checkThreadMethod = WebView.class.getDeclaredMethod("checkThread"); checkThreadMethod.setAccessible(true); checkThreadMethod.invoke(webview); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } } }
WebViewCompat { @SuppressWarnings("NewApi") private static void checkThread(WebView webview) { if (BuildCompat.isAtLeastP()) { if (webview.getWebViewLooper() != Looper.myLooper()) { throw new RuntimeException("A WebView method was called on thread '" + Thread.currentThread().getName() + "'. " + "All WebView methods must be called on the same thread. " + "(Expected Looper " + webview.getWebViewLooper() + " called on " + Looper.myLooper() + ", FYI main Looper is " + Looper.getMainLooper() + ")"); } } else { try { Method checkThreadMethod = WebView.class.getDeclaredMethod("checkThread"); checkThreadMethod.setAccessible(true); checkThreadMethod.invoke(webview); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } } private  WebViewCompat(); }
WebViewCompat { @SuppressWarnings("NewApi") private static void checkThread(WebView webview) { if (BuildCompat.isAtLeastP()) { if (webview.getWebViewLooper() != Looper.myLooper()) { throw new RuntimeException("A WebView method was called on thread '" + Thread.currentThread().getName() + "'. " + "All WebView methods must be called on the same thread. " + "(Expected Looper " + webview.getWebViewLooper() + " called on " + Looper.myLooper() + ", FYI main Looper is " + Looper.getMainLooper() + ")"); } } else { try { Method checkThreadMethod = WebView.class.getDeclaredMethod("checkThread"); checkThreadMethod.setAccessible(true); checkThreadMethod.invoke(webview); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } } private  WebViewCompat(); @SuppressWarnings("NewApi") @RequiresFeature(name = WebViewFeature.VISUAL_STATE_CALLBACK, enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported") static void postVisualStateCallback(@NonNull WebView webview, long requestId,
            @NonNull final VisualStateCallback callback); @SuppressLint("NewApi") @RequiresFeature(name = WebViewFeature.START_SAFE_BROWSING, enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported") static void startSafeBrowsing(@NonNull Context context,
            @Nullable ValueCallback<Boolean> callback); @SuppressLint("NewApi") @RequiresFeature(name = WebViewFeature.SAFE_BROWSING_WHITELIST, enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported") static void setSafeBrowsingWhitelist(@NonNull List<String> hosts,
            @Nullable ValueCallback<Boolean> callback); @SuppressLint("NewApi") @NonNull @RequiresFeature(name = WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL, enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported") static Uri getSafeBrowsingPrivacyPolicyUrl(); @Nullable static PackageInfo getCurrentWebViewPackage(@NonNull Context context); static @NonNull WebMessagePortCompat[] createWebMessageChannel(
            @NonNull WebView webview); static void postWebMessage(@NonNull WebView webview, @NonNull WebMessageCompat message,
            @NonNull Uri targetOrigin); }
WebViewCompat { @SuppressWarnings("NewApi") private static void checkThread(WebView webview) { if (BuildCompat.isAtLeastP()) { if (webview.getWebViewLooper() != Looper.myLooper()) { throw new RuntimeException("A WebView method was called on thread '" + Thread.currentThread().getName() + "'. " + "All WebView methods must be called on the same thread. " + "(Expected Looper " + webview.getWebViewLooper() + " called on " + Looper.myLooper() + ", FYI main Looper is " + Looper.getMainLooper() + ")"); } } else { try { Method checkThreadMethod = WebView.class.getDeclaredMethod("checkThread"); checkThreadMethod.setAccessible(true); checkThreadMethod.invoke(webview); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } } private  WebViewCompat(); @SuppressWarnings("NewApi") @RequiresFeature(name = WebViewFeature.VISUAL_STATE_CALLBACK, enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported") static void postVisualStateCallback(@NonNull WebView webview, long requestId,
            @NonNull final VisualStateCallback callback); @SuppressLint("NewApi") @RequiresFeature(name = WebViewFeature.START_SAFE_BROWSING, enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported") static void startSafeBrowsing(@NonNull Context context,
            @Nullable ValueCallback<Boolean> callback); @SuppressLint("NewApi") @RequiresFeature(name = WebViewFeature.SAFE_BROWSING_WHITELIST, enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported") static void setSafeBrowsingWhitelist(@NonNull List<String> hosts,
            @Nullable ValueCallback<Boolean> callback); @SuppressLint("NewApi") @NonNull @RequiresFeature(name = WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL, enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported") static Uri getSafeBrowsingPrivacyPolicyUrl(); @Nullable static PackageInfo getCurrentWebViewPackage(@NonNull Context context); static @NonNull WebMessagePortCompat[] createWebMessageChannel(
            @NonNull WebView webview); static void postWebMessage(@NonNull WebView webview, @NonNull WebMessageCompat message,
            @NonNull Uri targetOrigin);  }