我实施了一个自定义按钮,在我的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" />
谢谢!
我尝试了以下指令,我从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);
答案 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.