自定义视图适用于API 21,但在较低的API上获取ClassNotFoundexception

时间:2015-03-27 13:26:31

标签: java android android-fragments

当我使用API​​21在Android模拟器上运行我的应用程序时它工作正常,但当我在API16模拟器上运行我的应用程序时,我的片段膨胀时捕获错误。 错误示例

>  java.lang.RuntimeException: Unable to resume activity {ajax.ir.com.ajax/com.ir.ajax.activity.AuthentificationActivity}: android.view.InflateException: Binary XML file line **#57: Error inflating class com.ir.ajax.views.AJTextView**
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2575)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: android.view.InflateException: Binary XML file line #57: Error inflating class com.ir.ajax.views.AJTextView . . . .
Caused by: java.lang.ClassNotFoundException: com.ir.ajax.views.AJTextView
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
        at android.view.LayoutInflater.createView(LayoutInflater.java:552)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:749)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
        at com.ir.ajax.fragments.AuthentificationFragment.onCreateView(AuthentificationFragment.java:26)
        at android.support.v4.app.Fragment.performCreateView(Fragment.java:1786)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126)
        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489)
        at android.support.v4.app.FragmentActivity.onPostResume(FragmentActivity.java:434)
        at android.app.Activity.performResume(Activity.java:5095)
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2565)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)

此视图位于我的片段XML中,其中包含自定义视图:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aj="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">

<LinearLayout
    android:id="@+id/bttn_login"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal"
    android:paddingBottom="28dp"
    android:paddingTop="28dp">

    <View
        android:layout_width="1dp"
        android:layout_height="match_parent"
        android:background="@drawable/s_d_blue"
        android:duplicateParentState="true" />

    <!--<com.ir.ajax.views.AJButton
        android:id="@+id/bttn_enter"
        style="@style/ButtonBlueText"
        aj:typeface="os_light"
        android:text="@string/entry"
        android:onClick="onClick" />-->

    <Button
        android:id="@+id/bttn_enter"
        style="@style/ButtonBlueText"
        android:text="@string/entry"
        android:onClick="onClick" />

    <View
        android:layout_width="1dp"
        android:layout_height="match_parent"
        android:background="@drawable/s_d_blue"
        android:duplicateParentState="true" />
</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal"
    android:paddingBottom="28dp"
    android:paddingTop="28dp">

    <View
        android:layout_width="48dp"
        android:layout_height="1dp"
        android:background="@color/grey_500" />

    <com.ir.ajax.views.AJTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        aj:typeface="os_light"
        android:padding="8dp"
        android:text="@string/or"
        android:textColor="@color/grey_500"
        android:textSize="@dimen/text_size_36" />

    <View
        android:layout_width="48dp"
        android:layout_height="1dp"
        android:background="@color/grey_500" />
</LinearLayout>

<LinearLayout
    android:id="@+id/btnRegistration"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal"
    android:paddingBottom="28dp"
    android:paddingTop="28dp">

    <View
        android:layout_width="1dp"
        android:layout_height="match_parent"
        android:background="@drawable/s_d_blue"
        android:duplicateParentState="true" />

    <com.ir.ajax.views.AJButton
        android:id="@+id/bttn_register"
        style="@style/ButtonBlueText"
        aj:typeface="os_light"
        android:text="@string/registration"
        android:onClick="onClick" />

    <View
        android:layout_width="1dp"
        android:layout_height="match_parent"
        android:background="@drawable/s_d_blue"
        android:duplicateParentState="true" />
</LinearLayout>

<Button
    android:id="@+id/btnMenu"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="all_fragments"
    android:visibility="gone" />

<Button
    android:id="@+id/btnActivitis"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="all_activity"
    android:visibility="gone" />

碎片代码:

    package com.ir.ajax.fragments;

import android.graphics.Typeface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;

import com.ir.ajax.R;
import com.ir.ajax.activity.AuthentificationActivity;

public class AuthentificationFragment extends Fragment {


public void onCreate(Bundle savedInstanceState) {
    setHasOptionsMenu(false);
    super.onCreate(savedInstanceState);
}

//TODO
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_authentication, null);

    Typeface os_light = Typeface.createFromAsset(getActivity().getAssets(), "fonts/os_light.ttf");
    Button bttn_enter = (Button) view.findViewById(R.id.bttn_enter);
    bttn_enter.setTypeface(os_light);

    //TODO
    final AuthentificationActivity owner = (AuthentificationActivity) getActivity();
    if (owner != null) {
        view.findViewById(R.id.btnMenu).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                owner.showDialog();
            }
        });
    }
    if (owner != null) {
        view.findViewById(R.id.btnActivitis).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                owner.showDialogActivities();
            }
        });
    }

    return view;
}

}

我的自定义视图示例:

package com.ir.ajax.views;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;

import com.ir.ajax.utils.TextViewUtils;

public class AJTextView extends TextView {

public AJTextView(Context context) {
    this(context, null);
    TextViewUtils.initTypeface(this, context);
}

public AJTextView(Context context, AttributeSet attrs) {
    super(context, attrs);

    if (!isInEditMode()) {
        TextViewUtils.initTypeface(this, context, attrs);
    }
}

public AJTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    if (!isInEditMode()) {
        TextViewUtils.initTypeface(this, context, attrs);
    }
}

}

我的构建文件:

apply plugin: 'com.android.application'
apply plugin: 'sonar-runner'
android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"
    defaultConfig {
        applicationId "ajax.ir.com.ajax"
        minSdkVersion 16
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
        multiDexEnabled = true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            debuggable true
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
    productFlavors {
    }
    lintOptions {
        abortOnError false
    }
}
allprojects {
    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
        }
    }
}
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:21.0.3'
    compile 'com.google.android.gms:play-services:6.5.87'
    compile files('libs/nineoldandroids-2.4.0.jar')
    compile files('libs/universal-image-loader-1.9.3.jar')
    compile project(':qrscanner')
    compile files('libs/NettyClient-1.0-SNAPSHOT-jar-with-dependencies.jar')
    //compile 'com.android.support:support-v4:22.0.0'
    compile files('libs/support-v4-22.0.0-javadoc.jar')
}
sonarRunner {
    sonarProperties {
        property "sonar.host.url", "http://127.0.0.1:9000"
        property "sonar.jdbc.url", "jdbc:h2:tcp://localhost:9092/sonar"
        property "sonar.projectName", "Ajax"
        property "sonar.language", "java"
        property "sonar.sources", "src"
        property "sonar.binaries", "build"
    }
}

2 个答案:

答案 0 :(得分:1)

您的项目是否已达到65k +方法(dex限制)?您似乎已在build.gradle中启用了multidex。但这样做不足以支持multidex,您需要在Application类中扩展MultidexApplication

Android 5.0及更高版本使用名为ART的运行时,它本身支持从应用程序APK文件加载多个dex文件。这可能是您的应用在API 5.0 +

中正常运行的原因
public class YourApplication extends MultiDexApplication {

.

.

此外,您还需要在build.gradle中指定对multidex lib的依赖性

compile 'com.android.support:multidex:1.0.0'

你做过这个吗?

有关详细信息,请参阅此文档 https://developer.android.com/tools/building/multidex.html

答案 1 :(得分:0)

尝试以下代码,我不确定,但它可以提供帮助。

public class AJTextView extends TextView {

public AJTextView(Context context) {
    super(context);
    TextViewUtils.initTypeface(this, context);
}

public AJTextView(Context context, AttributeSet attrs) {
    super(context, attrs);

    if (!isInEditMode()) {
        TextViewUtils.initTypeface(this, context, attrs);
    }
}

public AJTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    if (!isInEditMode()) {
        TextViewUtils.initTypeface(this, context, attrs);
    }
}

}

您也可以尝试使用19 api作为目标sdk编译器。