膨胀自定义按钮时的ClassNotFoundException(适用于手机;平板电脑上的例外)

时间:2015-07-28 18:28:34

标签: java android classnotfoundexception layout-inflater custom-view

我实施了一个自定义按钮,在我的Nexus 5手机中没有任何问题。但是,当我尝试在三星Galaxy平板电脑(甚至是BQ爱迪生平板电脑)中运行它时,它会在给按钮充气时抛出ClassNotFoundException。

在调试和释放模式下抛出异常,没有和使用proguard。你有什么想法可能导致这个吗?有什么办法可以解决吗?

以下是例外:

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)

这是Java声明代码:

package com.appx.ui;
public class ExpandedTouchButton extends FrameLayout implements ViewTreeObserver.OnPreDrawListener {
   //...
}

这是布局XML文件中的Button用法:

<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" />

谢谢!

编辑1

我尝试了以下指令,我从LayoutInflater.createView()代码中复制了它,并抛出 ClassNotFoundException 。不管它是什么,它似乎是一个类加载问题。

Class clazz = getActivity().getClassLoader()
    .loadClass("com.appx.ui.ExpandedTouchButton")
        .asSubclass(View.class);

此外,以下代码抛出 NoClassDefFoundError ...

Class clazz = ExpandedTouchButton.class.getClassLoader()
    .loadClass("com.appx.ui.ExpandedTouchButton").asSubclass(View.class);

1 个答案:

答案 0 :(得分: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.