1

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);
luz
  • 73
  • 1
  • 6
  • are you using a library and if yes then have you added the library to your project ? – Aakash Jul 28 '15 at 18:32
  • Hi Aakash, the ExpandedTouchButton class is not in a library. It is in the app project. I don't think it would work on my phone otherwise :-) – luz Jul 28 '15 at 18:36
  • @luz,your problem is weird.Is tablet and phone both are using same layout? – Soham Jul 28 '15 at 19:49
  • Are you using build variants or is it exactly the same apk file for phones and tablets ? – BladeCoder Jul 28 '15 at 19:52
  • @Soham it is indeed strange, the layouts are all the same and (@BladeCoder) the apk is also the same. – luz Jul 28 '15 at 20:15

1 Answers1

1

Sorry, it seems like the information I posted would never be enough to reach an answer.

The problem was actually that I enabled multidexing (https://developer.android.com/intl/es/tools/building/multidex.html).

I did not properly setup multidexing (i.e. I did not configure my application as a MultiDexApplication in the Android manifest). Thus, my Nexus 5 with Android 5.1.1 was able to reach all the classes, but the Samsung tablet with 4.4.2 was not. I am assuming that the tablet was only searching for class files in one dex file (instead of the two that were generated).

I managed to reduce the amount of dependencies by importing only part of the google services library (com.google.android.gms:play-services-plus:7.5.0), instead of the whole library. In other words, I disabled multidexing and it worked.

luz
  • 73
  • 1
  • 6
  • 1
    The symptom is different, but there's a similar question here: http://stackoverflow.com/questions/27698287/noclassdeffounderror-with-android-studio-on-android-4 – luz Jul 28 '15 at 23:53