【问题标题】:NoSuchMethodError error when using Proguard for OnClickListener为 OnClickListener 使用 Proguard 时出现 NoSuchMethodError 错误
【发布时间】:2014-07-28 16:26:24
【问题描述】:

当使用 proguard 构建我的 android 应用程序时,一旦向用户显示第一个活动,应用程序就会完全崩溃:

java.lang.NoSuchMethodError: android.content.res.XmlResourceParser.i
       at ActivityNewUserSetup.OnClickOKButton()
       at ActivityNewUserSetup.onCreate()
       at android.app.Activity.performCreate(Activity.java:5231)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
       at android.app.ActivityThread.access$800(ActivityThread.java:135)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:136)
       at android.app.ActivityThread.main(ActivityThread.java:5017)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:515)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
       at dalvik.system.NativeStart.main(NativeStart.java)

它似乎引用的代码在 ActivityNewUserSetup 类中:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    ...code omitted for clarity
    Button btnOK = (Button) findViewById(R.id.btn_Confirm_Selection);
    btnOK.setOnClickListener(OnClickOKButton());
}

View.OnClickListener OnClickOKButton()
{
    return new View.OnClickListener()
    {
        public void onClick(View v)
        {
            ...code omitted for clarity
        }
     }
}

我使用了这里找到的基本 proguard 模板配置文件:

Android: What are the recommended configurations for Proguard?

如果是监听器触发了函数,我需要在 proguard 文件中添加什么来阻止它?

我的 proguard 版本是 4.7

【问题讨论】:

    标签: android obfuscation proguard


    【解决方案1】:

    得到了答案,错误信息是一条红鲱鱼。 Robert Rowntree 的回答让我了解了第 3 方套餐可能发生的情况。

    在这个活动中,我使用 ksoap2-android-assembly-3.2.0.jar,将以下内容添加到 proguard-project.txt

    -ignorewarnings
    -keep class org.kobjects.** { *; }
    -keep class org.ksoap2.** { *; }
    -keep class org.kxml2.** { *; }
    -keep class org.xmlpull.** { *; }
    

    它现在可以工作了,所以这里的课程是查看您的 3rd 方 Jar 文件并尝试在 proguard-project.txt 中放入大量 KEEP 语句以排除这种可能性。虽然不严格地回答问题 Robert Rowntree 提供了这样做的线索,但他会得到正确的答案。谢谢大家

    【讨论】:

      【解决方案2】:

      可能是 android sdk 的 lib jar ...

      -libraryjars  /usr/local/src/android-sdk-linux/platforms/android-19/android.jar
      -libraryjars <java.home>/lib/rt.jar
      

      对于像您的解析器这样的开源 api,您可以为这些包指定“保留”,如下面的示例,来自使用大量 OSS 的项目。

      -keep        class ch.boye.httpclientandroidlib.** { *; }
      -keep public class com.mobeta.android.** { *; }
      -keep        class com.slidingmenu.lib.** { *; }
      -keep        class org.codehaus.jackson.** { *; }
      -keep        class org.joda.time.** { *; }
      -keep        class com.google.android.gms.** { *; }
      -keep        class com.google.sample.castcompanionlibrary.cast.callbacks** { *; }
      -keep        class com.google.sample.castcompanionlibrary.cast.dialog.video** { *; }
      -keep        class com.google.sample.castcompanionlibrary.cast.exceptions** { *; }
      -keep        class com.google.sample.castcompanionlibrary.cast.player** { *; }
      -keep        class com.google.sample.castcompanionlibrary.notification** { *; }
      -keep        class com.google.sample.castcompanionlibrary.remotecontrol** { *; }
      -keep        class com.google.sample.castcompanionlibrary.utils** { *; }
      -keep        class com.google.sample.castcompanionlibrary.widgets** { *; }
      -keep        class android.support.v13.** { *; }
      -keep        class android.support.v7.** { *; }
      -keep        class android.support.v4.** { *; }
      -keep        class com.actionbarsherlock.** { *; }
      -keep        class com.androidquery.** { *; }
      

      您还可以阅读有关 api 的 proguard 提示。

      【讨论】:

      • 感谢 robert 的线索,这是一个 3rd 方 JAR 扔东西
      【解决方案3】:

      我试过你的代码,它对我有用。我发布了对我有用的唯一更改是我在 onclick 侦听器上添加了一个分号,我在您的代码中没有看到。代码如下:

      public class Sample extends Activity {
      Button button1;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          // TODO Auto-generated method stub
          super.onCreate(savedInstanceState);
          setContentView(R.layout.sample);
          button1 = (Button) findViewById(R.id.button1);
          button1.setOnClickListener(OnClickOKButton());
      }
      
      View.OnClickListener OnClickOKButton() {
          return new View.OnClickListener() {
              public void onClick(View v) {
                  Toast.makeText(Sample.this, "clicked", Toast.LENGTH_SHORT)
                          .show();
              }
          };//added semicolon here
      }
      }
      

      我的猜测是该函数在编译时可用,但在运行时不可用(虽然不太可能)。

      【讨论】:

      • 感谢您的回答,我的问题是错误有点像红鲱鱼。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-17
      • 2018-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-09
      • 2019-02-24
      相关资源
      最近更新 更多