I have a custom Button implemented that inflates with no problems in my Nexus 5 phone. However, when I try to run it in a Samsung Galaxy tablet (or even a BQ Edison tablet), it throws a ClassNotFoundException when inflating the Button.
The exception is thrown in both debug and release modes, without and with proguard. Do you have any ideas what might be causing this? Is there any way to solve it?
Here's the exception:
android.view.InflateException: Binary XML file line #38: Error inflating class com.appx.ui.ExpandedTouchButton
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:769)
at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
at com.appx.ui.animation.HowScreenFragment.onCreateView(HowScreenFragment.java:142)
at android.app.Fragment.performCreateView(Fragment.java:1700)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
at android.app.BackStackRecord.run(BackStackRecord.java:684)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1453)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5476)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.appx.ui.ExpandedTouchButton" on path: DexPathList[[zip file "/data/app/com.appx-4.apk"],nativeLibraryDirectories=[/data/app-lib/com.appx-4, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:67)
at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
at android.view.LayoutInflater.createView(LayoutInflater.java:565)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:702)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:769)
at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
at com.appx.ui.animation.HowScreenFragment.onCreateView(HowScreenFragment.java:142)
at android.app.Fragment.performCreateView(Fragment.java:1700)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
at android.app.BackStackRecord.run(BackStackRecord.java:684)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1453)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5476)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
Here's the Java declaration code:
package com.appx.ui;
public class ExpandedTouchButton extends FrameLayout implements ViewTreeObserver.OnPreDrawListener {
//...
}
And here's the Button usage in the layout XML file:
<com.appx.ui.ExpandedTouchButton
android:id="@+id/btnLogIn"
android:layout_width="240dp"
android:layout_height="44dp"
android:layout_gravity="center"
android:layout_marginTop="0dp"
android:textSize="20dp"
android:textColor="@color/text_white"
android:text="@string/log_in"
android:background="@drawable/login_button" />
Thanks!
Edit 1
I have tried the following instruction, which I copied from the LayoutInflater.createView() code and it throws the ClassNotFoundException. Whatever it is, it seems like a class loading issue.
Class clazz = getActivity().getClassLoader()
.loadClass("com.appx.ui.ExpandedTouchButton")
.asSubclass(View.class);
Also, the following code throws a NoClassDefFoundError...
Class clazz = ExpandedTouchButton.class.getClassLoader()
.loadClass("com.appx.ui.ExpandedTouchButton").asSubclass(View.class);