使用Proguard for OnClickListener时出现NoSuchMethodError错误

时间:2014-06-07 14:12:52

标签: android obfuscation proguard

当使用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

3 个答案:

答案 0 :(得分:3)

得到答案,错误信息是红鲱鱼。 Robert Rowntree的回答让我了解了第三方软件包可能发生的事情。

在本活动中,我使用kso​​ap2-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.** { *; }

它现在有效,所以这里的教训是查看你的第三方Jar文件,并尝试在proguard-project.txt中加载一些KEEP语句以排除这种可能性。虽然罗伯特·朗特里提出了解决问题的答案并不严格,但他会得到正确的答案。谢谢你们

答案 1 :(得分:1)

可能是android sdk的lib jar ......

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

OR

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

-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提示。

答案 2 :(得分:1)

我尝试了你的代码,它对我有用。我发布了对我有用的唯一变化是我在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
}
}

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