2

当应用程序从 Eclipse 通过 USB 安装时,我的应用程序将在我的目标设备 (HTC Desire HD) 上调试和运行完美。

但是,当我导出到 .APK 然后在我的 Desire HD 上安装这个 .APK(首先手动卸载了我之前安装的应用程序)时,它崩溃了。

检查 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>

在此先感谢您提供任何提示。如果需要任何其他提取或配置信息,请大声疾呼。

4

3 回答 3

3

这个问题现在已经通过使用proguard.cfg从新创建的测试项目中获取的完全标准和默认文件来解决。

正如我原来的问题所引用的那样,我之前使用的配置文件是我不得不在短时间内手动添加到项目中的一个,因为它丢失了。我现在不确定文件来自哪里——我很可能已经用谷歌搜索并找到了一个示例默认文件,然后就使用了它。

这是 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 引用类时才会调用这些构造函数。

于 2012-04-10T16:56:09.530 回答
0

在使用合并膨胀视图时未将您设置attachToRoot为 true 可能是 InflateException 的原因。

于 2012-04-09T20:53:59.993 回答
0

或者您可以将项目中的一个替换为默认的或 ${sdk.dir}/tools/proguard/proguard-android.txt 中优化的那个

于 2013-10-01T10:42:48.443 回答