Android 4.2.2(wiko)

时间:2015-09-22 18:06:09

标签: android proguard androiddesignsupport android-proguard android-support-design

我正在尝试使用Android支持设计库(版本23.0.1)和类NavigationMenu(我将此类用作布局中的XML标记)。

当我在Android 4.3上的三星或Android 5.x或6.0上的Nexus上执行我的应用程序时一切正常,但当我在Android 4.2.2上的Wiko Rainbow上执行应用程序时,它崩溃了以下内容例外:

java.lang.RuntimeException: Unable to start activity ComponentInfo{applicationId/package.MainActivity}: android.view.InflateException: Binary XML file line #11: Error inflating class <unknown>
[...]
Caused by: android.view.InflateException: Binary XML file line #11: Error inflating class <unknown> 
Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.constructNative(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
        at android.view.LayoutInflater.createView(LayoutInflater.java:587)
[...]
Caused by: java.lang.NoClassDefFoundError: android.support.design.internal.NavigationMenu
        at android.support.design.widget.NavigationView.<init>(NavigationView.java:99)
        at android.support.design.widget.NavigationView.<init>(NavigationView.java:92)
        at java.lang.reflect.Constructor.constructNative(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
        at android.view.LayoutInflater.createView(LayoutInflater.java:587)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
[...]

这个错误让我想起了几个月前开发人员在Android 4.2.2上的一些Wiko和Samsung手机上使用appcompat-v7库的情况。

错误是:

java.lang.NoClassDefFoundError:   android.support.v7.internal.view.menu.MenuBuilder
at android.support.v7.app.ActionBarActivityDelegateBase.initializePanelMenu(ActionBarActivityDelegateBase.java:914)
at android.support.v7.app.ActionBarActivityDelegateBase.preparePanel(ActionBarActivityDelegateBase.java:964)
at android.support.v7.app.ActionBarActivityDelegateBase.doInvalidatePanelMenu(ActionBarActivityDelegateBase.java:1182)
at android.support.v7.app.ActionBarActivityDelegateBase.access$100(ActionBarActivityDelegateBase.java:79)
at android.support.v7.app.ActionBarActivityDelegateBase$1.run(ActionBarActivityDelegateBase.java:118)
at android.os.Handler.handleCallback(Handler.java:800)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5391)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)

解决方案是将以下proguard文件用于项目:

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-dontobfuscate
-dontoptimize

-keep class !android.support.v7.internal.view.menu.**, ** { *; }

这个解决方案非常棒,因为我没有为像Jackson这样的其他库添加特定的规则(只有一些-dontwarn行),或者为android组件添加特定的规则。

因为NavigationMenu类继承了MenuBuilder类,我认为我们可以像这样修改proguard文件来解决问题:

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-dontobfuscate
-dontoptimize

-keep class !android.support.design.internal.**, ** { *; }

不幸的是它不起作用......所以我尝试了另一种解决方案:

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-dontobfuscate
-dontoptimize

-keep class !android.support.v7.internal.view.menu.*MenuBuilder*, android.support.v7.** { *; }

此解决方案可以但是......实际上,我没有NoClassDefFoundError例外,但我有其他例外(在所有Android版本上都会出现),例如:

  • 一些缺少的构造函数使用反射;
  • 杰克逊对象或Fragment上缺少一些空构造函数。

那么,你知道一个解决方案,允许我在Android 4.2.2上的Wiko上执行我的应用程序吗?我不需要为我使用或将来使用的每个库添加特定规则吗? / p>

提前感谢您的帮助!

5 个答案:

答案 0 :(得分:5)

我跟随类似的thread并努力寻找解决方案,但我没有设备。

根据人们的评论,我在proguard配置中添加了以下内容 构建类型:

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-project.txt'
    }
}

proguard的-project.txt

-repackageclasses ''
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }

-keep class android.support.v7.app.** { *; }
-keep interface android.support.v7.app.** { *; }

-keep class android.support.v13.app.** { *; }
-keep interface android.support.v13.app.** { *; }

您可以尝试使用以下配置吗? 我对这个解决方案有一些疑问,因为当我有未定义的生成类时,我仍然在同一个包中有NavigationMenuView。由于它的包访问关系,它没有被移动。所以可能有帮助的是在proguard-project.txt配置中添加另一个标志,但风险很大:

-allowaccessmodification

这可能是尝试解决问题的良好开端。

所以在你的情况下,proguard-project应该是这样的:

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-dontobfuscate
-dontoptimize
-allowaccessmodification
-repackageclasses ''
-keep class your.package.name.** { *; }
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }

-keep class android.support.v7.app.** { *; }
-keep interface android.support.v7.app.** { *; }

-keep class android.support.v13.app.** { *; }
-keep interface android.support.v13.app.** { *; }

答案 1 :(得分:0)

我要这样做。我还没有尝试过,因为我没有任何受影响的设备:

case class Task(id: Long, color: String, status: TaskStatus.Value, project: Long)

object TaskStatus extends Enumeration {
  val ready = Value("ready")
  val set = Value("set")
  val go = Value("go")
}

class TaskRepo @Inject()(protected val dbConfigProvider: DatabaseConfigProvider) {
  val dbConfig = dbConfigProvider.get[JdbcProfile]
  import dbConfig.driver.api._
  private val Tasks = TableQuery[TasksTable]

  def findByReadyStatus: DBIO[List[Task]] =
    Tasks.filter(_.status === TaskStatus.ready).to[List].result

  private class TasksTable(tag: Tag) extends Table[Task](tag, "TASK") {

    def id = column[Long]("ID", O.AutoInc, O.PrimaryKey)
    def color = column[String]("COLOR")
    def status = column[TaskStatus.Value]("STATUS")
    def project = column[Long]("PROJECT")

    def * = (id, color, status, project) <> (Task.tupled, Task.unapply _)
    def ? = (id.?, color.?, status.?, project.?).shaped.<>({ r => import r._; _1.map(_ => Task.tupled((_1.get, _2.get, _3.get, _4.get))) }, (_: Any) => throw new Exception("Inserting into ? Taskion not supported."))
  }

  implicit val taskStatusColumnType = MappedColumnType.base[TaskStatus.Value, String](
    _.toString, string => TaskStatus.withName(string))

}

除此规则之外,它还可以帮助许多三星设备(请参阅http://goo.gl/ywG1c4):

-keep class !android.support.design.internal.NavigationMenu,!android.support.design.internal.NavigationMenuPresenter,!android.support.design.internal.NavigationSubMenu

答案 2 :(得分:-1)

-

   -keep class !android.support.v7.internal.view.menu.**,** {*;}
   -keep class android.support.v4.** { *; }
   -keep interface android.support.v4.** { *; }
   -keep class android.support.v7.** { *; }
   -keep interface android.support.v7.** { *; }

答案 3 :(得分:-1)

检查com.android.support:appcompat版本。例如, 而不是com.android.support:appcompat-v7:23.1.1尝试使用com.android.support:appcompat-v7:23.0.1

答案 4 :(得分:-4)

为Szymon Klimaszewski求助!这里的proguard文件对我有用:

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-dontobfuscate
-dontoptimize
-repackageclasses ''

#Jackson
-dontwarn com.fasterxml.jackson.databind.**

#View Pager Indicator
-dontwarn com.viewpagerindicator.**

#Android
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class android.support.v7.app.** { *; }
-keep interface android.support.v7.app.** { *; }
-keep class android.support.v13.app.** { *; }
-keep interface android.support.v13.app.** { *; }

#droid4me
-keep class com.smartnsoft.** { *; }

#my app
-keep class my.app.package.** { *; }

#Critercism
-keep public class com.crittercism.**
-keepclassmembers public class com.crittercism.* { *; }