0

我的应用程序的目的是:用户输入一个数字并单击一个按钮。该按钮使用输入来计算带有计时器的斐波那契数列 - 序列中的每个数字每秒都显示给 textView。但是当我尝试运行计时器时,我得到了 CalledFromWrongThreadException。我已经在下面发布了我的代码。从我的日志语句可以看出,我相信我知道是哪一行导致了问题。我认为这是因为我正在调用我的 onclicklistener 之外的方法,但是当我移动其他方法时,我只会导致更多问题。

我已经阅读了其他几篇文章,但我不确定使用我的方法打印到文本区域的正确方法是什么。有谁知道我怎样才能使这项工作?

public class MainActivity extends Activity {

// primary widgets
private EditText editText;
private TextView textView;
private Button button1;

static int seconds = 0;
static Timer timer;

static ArrayList<Integer> fibList = new ArrayList<Integer>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    editText = (EditText) findViewById(R.id.editText1);
    textView = (TextView) findViewById(R.id.textView2);
    button1 = (Button) findViewById(R.id.button1);

    final int delay = 1000;
    final int period = 1000;
    timer = new Timer();

    //Attempt to clear TextView
    textView.setText("");

    button1.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            //Clear Textview
            String array = " "; 
            fibList.clear();
            textView.setText(array);
            //Log.i("ARRAY", "ATTEMPT to CLEAR"+fibList);

            String input = editText.getText().toString();
            int number = Integer.parseInt(input);
            int tmp = 0;

            // confirm input
            if (number < 20) {
                Toast.makeText(getApplicationContext(),
                        "You entered: " + number, Toast.LENGTH_LONG).show();
                for (int i = 0; i <= number; i++) {
                    fibList.add(fib(i));

                    // sum even numbers
                    if (fib(i) % 2 == 0) {
                        tmp += fib(i);

                    }

                }
            } else {
                Toast.makeText(getApplicationContext(),
                        "Number is too Large: " + number, Toast.LENGTH_LONG)
                        .show();
            }


            //I believe error occurs in this method

             Log.i("TEST", "START TIMER");
             timer.scheduleAtFixedRate(new TimerTask() {

                    public void run() {      
                             Log.i("TEST", "RUN TIMER");
                        int nextIndex = setInterval();
                        Log.i("TEST", "SET INTERVAL");
                          if (nextIndex < fibList.size()) {
                              Log.i("TEST", "TRY TO PRINT");

                              //It looks like error occurs here when I try to print to textView
                              textView.setText(fibList.get(nextIndex)+ " ");
                              Log.i("TEST", "NEXT INDEX"+fibList.get(nextIndex));
                              Log.i("TEST", "DID PRINT");
                          }
                    }
                }, delay, period);
             Log.i("TEST", "END TIMER");

        }

    });

}

// run fibonacci sequence
public static int fib(int n) {
    if (n < 2) {
        return n;
    } else {
        return fib(n - 1) + fib(n - 2);
    }
}

//counts up for every element through the array
    public static final int setInterval() {

        if (seconds >= fibList.size())
            timer.cancel();
        return seconds++;

    }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

}

4

3 回答 3

1

您可以使用

runOnUiThread(new Runnable(){
     public void run(){
     textView.setText("aaa"); 
    } 
});
于 2013-05-09T19:59:27.260 回答
0

让您的计时器向处理程序发布消息。默认情况下,处理程序将在主线程上运行。然后 IT 可以根据需要更改 UI,因此只需将计时器的主体放入该处理程序中。

于 2013-05-09T19:58:20.850 回答
0

我刚刚遇到了这个问题,然后来到 StackOverflow 来查看解决方案。没有找到任何合适的东西,但更多地尝试了很多日志和调试让我得到了解决方案。

getActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
              textView.setText("Your String");                                     
    }                    
});

在我的代码中,问题是由于我使用TextView.post(new Runnable...). 我猜这是因为它无法访问 UI 线程(因为它正忙于以前的线程更改)。在 UI Thread 中将两个 TextViews 一起设置解决了这个问题。因此,在这里发布给其他可能对类似问题感到困惑的人。希望能帮助到你。

于 2017-03-01T16:59:11.977 回答