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

2

Мое приложение будет отлично отлаживаться и работать на моем целевом устройстве (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.

<code>-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 *;
}
</code>

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

<code><?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>
</code>

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

Ах да, вы можете отключить запутывание тоже (-dontobfuscate) dmon
@dmon - Большое спасибо, я попробую. Я только что понял, что, учитывая, что Proguard включен и запутывает имена моих классов, как это должно быть (что я подтвердил, проверив, что mapping.txt был сгенерирован во время сборки релиза, которую я в последний раз пытался), конечно же, есть & apos; Что-то не так в том факте, что макет XML раздувается и ссылается на мойView класс по оригинальному названию! Предположительно, Proguard необходимо настроить таким образом, чтобы запутанные имена классов компоновки каким-то образом подставлялись в ресурсы XML до того, как они были сжаты. Я исследую это сейчас. Trevor
Вы пытались получить доступ кDashboardLayout объект в деятельности? Попробуйте сделать это, чтобы увидеть, если это proguard тот, который удаляет класс. На самом деле, вы также можете открыть банку DEXed, чтобы увидеть, есть ли там класс. Если это не так, то, скорее всего, это proguard. dmon
Пожалуйста, поделитесь XML-файл, который вызывает инфляцию. Anurag Ramdasan
@ Анураг Рамдасан - Хорошо, спасибо. Я сейчас добавил макет XML. Trevor

Ваш Ответ

3   ответа
0

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

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

зированный в $ {sdk.dir} /tools/proguard/proguard-android.txt

Похожие вопросы