I am using the StrictMode
in order to find non-SDK usages:
if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectNonSdkApiUsage()
.penaltyLog()
.build());
}
Now I am getting a policy violation:
D/StrictMode: StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Landroid/view/textclassifier/logging/ SmartSelectionEventTracker$SelectionEvent;->selectionAction(IIILandroid/view/textclassifier/TextClassification;)Landroid/view/textclassifier/logging/ SmartSelectionEventTracker$SelectionEvent;
at android.os.StrictMode.lambda$static$1(StrictMode.java:428)
at android.os.-$$Lambda$StrictMode$lu9ekkHJ2HMz0jd3F8K8MnhenxQ.accept(Unknown Source:2)
at java.lang.Class.getDeclaredMethodInternal(Native Method)
at java.lang.Class.getPublicMethodRecursive(Class.java:2075)
at java.lang.Class.getMethod(Class.java:2063)
at java.lang.Class.getMethod(Class.java:1690)
at bzi.a(SourceFile:11)
at bzq.a(SourceFile:12)
at org.chromium.content.browser.selection.SmartSelectionClient.<init>(SourceFile:5)
at bzZ.a(Unknown Source:7)
at org.chromium.android_webview.AwContents.e(SourceFile:193)
at org.chromium.android_webview.AwContents.d(SourceFile:153)
at org.chromium.android_webview.AwContents.<init>(SourceFile:81)
at uY.run(SourceFile:15)
at ahv.a(SourceFile:13)
at ahw.run(SourceFile:2)
at org.chromium.base.ThreadUtils.b(SourceFile:31)
at ahv.a(SourceFile:7)
at com.android.webview.chromium.WebViewChromiumFactoryProvider.b(SourceFile:6)
at com.android.webview.chromium.WebViewChromium.init(SourceFile:111)
at android.webkit.WebView.<init>(WebView.java:678)
at android.webkit.WebView.<init>(WebView.java:604)
at android.webkit.WebView.<init>(WebView.java:587)
at android.webkit.WebView.<init>(WebView.java:574)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at android.view.LayoutInflater.createView(LayoutInflater.java:647)
at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58)
at android.view.LayoutInflater.onCreateView(LayoutInflater.java:720)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:788)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at com.mine.ui.events.EventScreen.onCreateView(EventScreen.java:70)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2354)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1419)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:799)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:781)
(... shortened ...)
The important line is:
at com.mine.ui.events.EventScreen.onCreateView(EventScreen.java:70)
Examining the mentioned line:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// This is the important line:
ViewGroup content = (ViewGroup) inflater.inflate(R.layout.mine_event, container, false);
WebView webView = (WebView) content.findViewById(R.id.container);
webView.loadUrl(event.getWebViewUrl());
webView.getSettings().setJavaScriptEnabled(true);
(...)
So I get the violation while the inflation happens, which I dont quite understand.
As you can see shortly after the mentioned line a WebView
comes into play. I have looked at the source-code for the SmartSelectionEventTracker
here and it seems like a generic class for Widgets like TextViews, WebViews, ...
.
WebViews
seem to be related to MockViews
which are related to TextViews
.
But apart from that finding I do not understand how / why the violation is happening and what I can do against it.
Can someome explain this to me?
In Android P, restrictions have been added to private APIs (that is, APIs that are not part of the public SDK and are accessed via reflection). See Restrictions on non-SDK interfaces:
Android 9 (API level 28) introduces new restrictions on the use of non-SDK interfaces, whether directly, via reflection, or via JNI. These restrictions are applied whenever an app references a non-SDK interface or attempts to obtain its handle using reflection or JNI. For more information about this decision, see Improving Stability by Reducing Usage of non-SDK Interfaces.
So that's what you're seeing -- it's a warning that something is accessing one of those private APIs that may be removed in the future. However, the stack trace shows, as you mentioned, that this is coming from the WebView
. In particular, during the initialization of SmartSelectionClient
. That initializes a native library that implicitly is accessing SmartSelectionEventTracker
, which is marked with @hide
in its Javadoc statement, which indicates it is not part of the public SDK.
In short, there's likely nothing you can do about this particular warning, so I wouldn't worry about it. It's happening in the device's Chromium WebView
implementation, so it's outside of your application's control. As both Android and Chromium are published by Google, if there is a legitimate issue in a future release, an update will be published to the WebView
implementation before it becomes a problem.