为什么应用程序会抛出NoSuchMethodError异常

3

我有一个ProgressBar,当它发生改变时会调用另一个函数,但是偶尔我的应用程序会崩溃并抛出NoSuchMethodError。我包含了我的部分代码以及堆栈跟踪来帮助我解决这个问题。

我的Java部分代码:

public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
        ShowText();
        switch(seekBar.getId()) {
            case R.id.syst_bar:
                ShowText();
                progress = progress + 70;
                tvSVal.setText(String.valueOf(progress));
                if (progress == 70) {
                    tvSOne.setTextColor(Color.parseColor("#4E9CD2"));
                    tvSTwo.setTextColor(Color.WHITE);
                }
                else if (progress == 190) {
                    tvSOne.setTextColor(Color.WHITE);
                    tvSTwo.setTextColor(Color.parseColor("#4E9CD2"));
                }
                else {
                    tvSOne.setTextColor(Color.WHITE);
                    tvSTwo.setTextColor(Color.WHITE);
                }
            break;
            case R.id.dias_bar:
                ShowText();
                progress = progress + 40;
                tvDVal.setText(String.valueOf(progress));
                if (progress == 40) {
                    tvDOne.setTextColor(Color.parseColor("#4E9CD2"));
                    tvDTwo.setTextColor(Color.WHITE);
                }
                else if (progress == 100) {
                    tvDOne.setTextColor(Color.WHITE);
                    tvDTwo.setTextColor(Color.parseColor("#4E9CD2"));
                }
                else {
                    tvDOne.setTextColor(Color.WHITE);
                    tvDTwo.setTextColor(Color.WHITE);
                }
            break;
        default:
            break;
        }
    }

public void ShowText() {
    int inOne = sbSyst.getProgress() + 70;
    int inTwo = sbDias.getProgress() + 40;

    Log.i("SYSTOLIC SHOWTEXT", String.valueOf(inOne));
    Log.i("DIASTOLIC SHOWTEXT", String.valueOf(inTwo));

    if ((inOne >= 70 && inOne <= 90) && (inTwo >= 40 && inTwo <= 60)) {
        tvRes.setText("LOW");
        tvRes.setBackgroundColor(Color.parseColor("#73539E"));
        tvSVal.setBackground(getResources().getDrawable(R.drawable.lowtextpress));
        tvDVal.setBackground(getResources().getDrawable(R.drawable.lowtextpress));
    }
    if ((inOne >= 70 && inOne <= 90) && (inTwo >= 61 && inTwo <= 80)) {
        tvRes.setText("IDEAL");
        tvRes.setBackgroundColor(Color.parseColor("#679800"));
        tvSVal.setBackground(getResources().getDrawable(R.drawable.idealtextpress));
        tvDVal.setBackground(getResources().getDrawable(R.drawable.idealtextpress));
    }
    if ((inOne >= 70 && inOne <= 90) && (inTwo >= 81 && inTwo <= 90)) {
        tvRes.setText("PRE-HIGH");
        tvRes.setBackgroundColor(Color.parseColor("#967400"));
        tvSVal.setBackground(getResources().getDrawable(R.drawable.prehightextpress));
        tvDVal.setBackground(getResources().getDrawable(R.drawable.prehightextpress));
    }
    if ((inOne >= 70 && inOne <= 90) && (inTwo >= 91 && inTwo <= 100)) {
        tvRes.setText("HIGH");
        tvRes.setBackgroundColor(Color.parseColor("#960000"));
        tvSVal.setBackground(getResources().getDrawable(R.drawable.hightextpress));
        tvDVal.setBackground(getResources().getDrawable(R.drawable.hightextpress));
    }

    if ((inOne >= 91 && inOne <= 120) && (inTwo >= 40 && inTwo <= 80)) {
        tvRes.setText("IDEAL");
        tvRes.setBackgroundColor(Color.parseColor("#679800"));
        tvSVal.setBackground(getResources().getDrawable(R.drawable.idealtextpress));
        tvDVal.setBackground(getResources().getDrawable(R.drawable.idealtextpress));
    }
    if ((inOne >= 91 && inOne <= 120) && (inTwo >= 81 && inTwo <= 90)) {
        tvRes.setText("PRE-HIGH");
        tvRes.setBackgroundColor(Color.parseColor("#967400"));
        tvSVal.setBackground(getResources().getDrawable(R.drawable.prehightextpress));
        tvDVal.setBackground(getResources().getDrawable(R.drawable.prehightextpress));
    }
    if ((inOne >= 91 && inOne <= 120) && (inTwo >= 91 && inTwo <= 100)) {
        tvRes.setText("HIGH");
        tvRes.setBackgroundColor(Color.parseColor("#960000"));
        tvSVal.setBackground(getResources().getDrawable(R.drawable.hightextpress));
        tvDVal.setBackground(getResources().getDrawable(R.drawable.hightextpress));
    }

    if ((inOne >= 121 && inOne <= 140) && (inTwo >= 40 && inTwo <= 90)) {
        tvRes.setText("PRE-HIGH");
        tvRes.setBackgroundColor(Color.parseColor("#967400"));
        tvSVal.setBackground(getResources().getDrawable(R.drawable.prehightextpress));
        tvDVal.setBackground(getResources().getDrawable(R.drawable.prehightextpress));
    }
    if ((inOne >= 121 && inOne <= 140) && (inTwo >= 91 && inTwo <= 100)) {
        tvRes.setText("HIGH");
        tvRes.setBackgroundColor(Color.parseColor("#960000"));
        tvSVal.setBackground(getResources().getDrawable(R.drawable.hightextpress));
        tvDVal.setBackground(getResources().getDrawable(R.drawable.hightextpress));
    }
    if ((inOne >= 141 && inOne <= 190) && (inTwo >= 40 && inTwo <= 100)) {
        tvRes.setText("HIGH");
        tvRes.setBackgroundColor(Color.parseColor("#960000"));
        tvSVal.setBackground(getResources().getDrawable(R.drawable.hightextpress));
        tvDVal.setBackground(getResources().getDrawable(R.drawable.hightextpress));
    }
}

我的LogCat

java.lang.NoSuchMethodError: android.widget.TextView.setBackground
at com.sikni8.bloodpressurelite.MainActivity.ShowText(MainActivity.java:231)
at com.sikni8.bloodpressurelite.MainActivity.onProgressChanged(MainActivity.java:171)
at android.widget.SeekBar.onProgressRefresh(SeekBar.java:89)
at android.widget.ProgressBar.doRefreshProgress(ProgressBar.java:609)
at android.widget.ProgressBar.refreshProgress(ProgressBar.java:621)
at android.widget.ProgressBar.setProgress(ProgressBar.java:670)
at android.widget.AbsSeekBar.trackTouchEvent(AbsSeekBar.java:411)
at android.widget.AbsSeekBar.onTouchEvent(AbsSeekBar.java:342)
at android.view.View.dispatchTouchEvent(View.java:5553)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2019)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1712)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2019)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1712)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2019)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1712)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2019)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1712)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2019)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1712)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1930)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1389)
at android.app.Activity.dispatchTouchEvent(Activity.java:2378)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1878)
at android.view.View.dispatchPointerEvent(View.java:5733)
at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3104)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2666)
at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:900)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2675)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4624)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
at dalvik.system.NativeStart.main(Native Method)

我该如何修改代码,以免抛出异常或者使用更好的错误处理方法?


不是修改代码的问题,而是你的程序在运行时找不到一个类,你需要确保包含该类的jar文件已经被包含在你的类路径中。 - morgano
尝试使用setBackgroundResource替代。这是文档链接:http://developer.android.com/reference/android/view/View.html#setBackgroundResource(int) - Peshal
3个回答

5
请使用TextView.setBackgroundResource(int)方法,将drawable资源ID传递给它,如下所示:
tvRes.setBackgroundColor(Color.parseColor("#73539E"));
tvSVal.setBackgroundResource(R.drawable.lowtextpress);
tvDVal.setBackgroundResource(R.drawable.lowtextpress);

不知道这个奇怪的错误从哪里来,但无论如何,这是一个更好的解决方案。


你说得对。我支持4.0及更高版本,这就是为什么它会崩溃的原因 :) 我会相应地修改我的代码。谢谢 - SearchForKnowledge
太好了!如果这对您有帮助,请通过点击绿色复选框接受答案。谢谢! - Haldean Brown

2

setBackground() 只能在 api 等级 16 及以上使用。由于您的情况 api 等级设置为低于 16,因此请使用 setBackgroundDrawable()

api 等级低于 16 的手机将支持

setBackgroundDrawable()

或者你可以这样做:

if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN ) {
    myTextView.setBackground(d);
}
else {
    myTextView.setBackgroundDrawable(d);
}

你是正确的。我支持4.0及以上版本,这就是为什么它会崩溃的原因 :) 我会相应地更改代码。谢谢 - SearchForKnowledge

2
有两种常见的NoSuchMethodError场景:
1)您在代码中使用的API方法与运行时jar版本不同
2)您使用的Jar(X)依赖于Jar(Y) -> 但在运行时,您有不兼容的Jar(Y)。
编辑:
对于问题1,如何防止它?
这很容易处理,将一个jar添加到lib并在编译器路径中添加相同的jar(如果是eclipse,请添加库部分)
对于问题2,为什么会发生这种情况?
如果你下载了需要jar Y的Jar X,那么你会去互联网上下载,但不太关心哪个版本的Y与X兼容。
我们如何防止这种情况? 从Jar X的readme.txt中阅读并下载支持的Y版本。
是否有任何方法可以同时避免两种情况?
没有通用的答案,您需要正确阅读文档,而不是简单地下载并放入类路径中。

对于问题 #1 我该如何防止它?对于问题 #2 为什么会发生?有没有办法同时预防两个问题? - SearchForKnowledge
那个函数是main代码的一部分,为什么会不同呢? - SearchForKnowledge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接