android.view.WindowInsets
is added in API level 20.
I import android.view.WindowInsets
in my CustomLayout
and override onApplyWindowInsets(WindowInsets insets)
, but ClassNotFoundException
occurs in some phones, whose api level are from 14 to 21. What is the reason?
Occurred on: Rooted Nexus 5, Android 4.4.2
Stack trace:
Fatal Exception: java.lang.NoClassDefFoundError: android/view/WindowInsets
at java.lang.Class.getDeclaredMethods(Class.java)
at java.lang.Class.getDeclaredMethods(Class.java:656)
at android.view.ViewDebug.getExportedPropertyMethods(ViewDebug.java:960)
at android.view.ViewDebug.exportMethods(ViewDebug.java:1047)
at android.view.ViewDebug.dumpViewProperties(ViewDebug.java:997)
at android.view.ViewDebug.dumpViewProperties(ViewDebug.java:983)
at android.view.ViewDebug.dumpView(ViewDebug.java:900)
at android.view.ViewDebug.dumpViewHierarchy(ViewDebug.java:855)
at android.view.ViewDebug.dumpViewHierarchy(ViewDebug.java:867)
at android.view.ViewDebug.dumpViewHierarchy(ViewDebug.java:867)
at android.view.ViewDebug.dumpViewHierarchy(ViewDebug.java:867)
at android.view.ViewDebug.dumpViewHierarchy(ViewDebug.java:867)
at android.view.ViewDebug.dumpViewHierarchy(ViewDebug.java:867)
at android.view.ViewDebug.dumpViewHierarchy(ViewDebug.java:867)
at android.view.ViewDebug.dump(ViewDebug.java:793)
at android.view.ViewDebug.dispatchCommand(ViewDebug.java:416)
at android.view.ViewRootImpl$W.executeCommand(ViewRootImpl.java:6258)
at android.view.IWindow$Stub.onTransact(IWindow.java:65)
at android.os.Binder.execTransact(Binder.java:404)
at dalvik.system.NativeStart.run(NativeStart.java)
Caused by java.lang.ClassNotFoundException: Didn't find class "android.view.WindowInsets" on path: DexPathList[[zip file "/data/app/***-1.apk"],nativeLibraryDirectories=[/data/app-lib/***-1, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
at java.lang.Class.getDeclaredMethods(Class.java)
at java.lang.Class.getDeclaredMethods(Class.java:656)
at android.view.ViewDebug.getExportedPropertyMethods(ViewDebug.java:960)
at android.view.ViewDebug.exportMethods(ViewDebug.java:1047)
at android.view.ViewDebug.dumpViewProperties(ViewDebug.java:997)
at android.view.ViewDebug.dumpViewProperties(ViewDebug.java:983)
at android.view.ViewDebug.dumpView(ViewDebug
The system traverses all public methods of a view and encounters the overridden onApplyWindowInsets
with WindowInsets
parameter. This type does not exist in the system hence the crash.
Lollipop introduced the View.onApplyWindowInsets
method but it also introduced the OnApplyWindowInsetsListener
, which if set, is invoked instead of the aforementioned method.
I've had reports of this on Samsung devices running Android 4.4.
It can be triggered by dumping view hierarchy.
So far this doesn't solve anything. To the rescue comes support-v4 library:
public class SampleView extends View {
public SampleView(final Context context) {
this(context, null);
}
public SampleView(final Context context, @Nullable final AttributeSet attrs) {
this(context, attrs, 0);
}
public SampleView(final Context context, @Nullable final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
ViewCompat.setOnApplyWindowInsetsListener(this, new android.support.v4.view.OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(final View v, final WindowInsetsCompat insets) {
// Do whatever you needed to do in the first place...
return insets.consumeSystemWindowInsets();
}
});
}
}
Use the above in your common constructor. WindowInsetsCompat
is provided by the support-v4 library so it's always present, it does not expose any non-existent future classes directly on the view, and the code is effective only since Lollipop (where actual WindowInsets
were introduced).
Beats me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With