2

Вопрос по android, java – Приложение работает в режиме отладки / запуска из Eclipse, но .APK выдает исключение .classNotFoundException при синтаксическом анализе макета XML, содержащего пользовательское представление

Мое приложение будет отлично отлаживаться и работать на моем целевом устройстве (HTC Desire HD), если приложение установлено через USB от Eclipse.

Однако, когда я экспортирую в .APK и затем устанавливаю этот .APK на свой Desire HD (предварительно вручную удалив предыдущую установку моего приложения), происходит сбой.

Изучив ошибку в Logcat, я вижу, чтоView мой, на который ссылается, используя его полное имя в XML-файле макета, по-видимому, не может быть найден и приводит к.classNotFoundException.

Две линии интереса от трассировки ошибок Logcat:

04-09 21:29:01.101: E/AndroidRuntime(2157): Caused by: android.view.InflateException: Binary XML file line #12: Error inflating class com.trevp.myAppName.DashboardLayout

И еще ниже:

04-09 21:29:01.101: E/AndroidRuntime(2157): Caused by: java.lang.ClassNotFoundException: com.trevp.myAppName.DashboardLayout in loader dalvik.system.PathClassLoader[/data/app/com.trevp.myAppName-1.apk

Этот сбой не происходит при установке приложения из Eclipse, только при установке из экспортированного .APK.

В случае, если это может быть проблемой Proguard, вот мой файл конфигурации Proguard. Я не коснулся его по умолчанию, так как я новичок в использовании Proguard. Моя версия Proguard 4.7.

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

Файл XML, который надувается. (Merge теги используются, потому что элементы внутри добавляются как дочерние элементы к родителюFrameLayout.)

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <ImageView   
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_gravity="top|left"
    android:scaleType="centerCrop"
    android:id="@+id/dashLayoutImage"
    android:src="@drawable/background2" android:drawingCacheQuality="high"/>

    <com.trevp.myAppName.DashboardLayout
    android:clipChildren="false"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/dashLayout"
    android:layout_gravity="top|left" />

    <include
    android:layout_gravity="top|left"
    layout="@layout/status_bar"
    android:id="@+id/statusBar" />

    <TextView
    android:layout_gravity="bottom|left"
    android:id="@+id/pollRate"
     android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >
    </TextView>

</merge>

Заранее спасибо за любые советы по этому вопросу. Пожалуйста, кричите, если есть какие-либо другие выдержки или информация о конфигурации требуется.

@dmon - Большое спасибо, я попробую. Я только что понял, что, учитывая, что Proguard включен и запутывает имена моих классов, как это должно быть (что я подтвердил, проверив, что mapping.txt был сгенерирован во время сборки релиза, которую я в последний раз пытался), конечно же, есть & apos; Что-то не так в том факте, что макет XML раздувается и ссылается на мой<code>View</code> класс по оригинальному названию! Предположительно, Proguard необходимо настроить таким образом, чтобы запутанные имена классов компоновки каким-то образом подставлялись в ресурсы XML до того, как они были сжаты. Я исследую это сейчас.

Apr 10, 2012, 7:43 AMот

Ах да, вы можете отключить запутывание тоже (<code>-dontobfuscate</code>)

Apr 10, 2012, 1:59 PMот

Пожалуйста, поделитесь XML-файл, который вызывает инфляцию.

Apr 09, 2012, 8:44 PMот

Вы пытались получить доступ к<code>DashboardLayout</code> объект в деятельности? Попробуйте сделать это, чтобы увидеть, если это proguard тот, который удаляет класс. На самом деле, вы также можете открыть банку DEXed, чтобы увидеть, есть ли там класс. Если это не так, то, скорее всего, это proguard.

Apr 10, 2012, 12:28 AMот

@ Анураг Рамдасан - Хорошо, спасибо. Я сейчас добавил макет XML.

Apr 09, 2012, 8:47 PMот

3ответа

3

Эта проблема была решена с помощью полностью стандартного и стандартногоproguard.cfg файл взят из недавно созданного тестового проекта.

Файл конфигурации, который я использовал ранее, как указано в моем первоначальном вопросе, был тем, который мне пришлось добавить в проект вручную некоторое время назад, потому что он отсутствовал. Я не уверен, откуда этот файл появился. Я, скорее всего, нашел Google, нашел образец файла по умолчанию и просто использовал его.

Вот то, что Eclipse вложил в новый проект для меня, и это позволило работать .APK.

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*


-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

Я вижу, что различия в-keepclass* введите инструкции.

Теперь я приложу больше усилий, чтобы понять, как настроить Proguard!

Ради интереса рассмотрим следующие строки:

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

Похоже, они там для сохраненияView конструкторы (или сохраняющие классы, которые их содержат), которые будут вызываться только при обращении к классу из XML.

0

не устанавливая свойattachToRoot Значение true, в то время как раздувание представления слиянием может быть причиной исключения InflateException.

0

Или вы можете просто заменить один в проекте на стандартный или оптимизированный в $ {sdk.dir} /tools/proguard/proguard-android.txt

RelatedQuestions