函数和Runnable同时工作(如何?)(Android,Java)

时间:2013-07-06 10:39:38

标签: java android handler runnable

我有一个Android应用,在按下按钮后会启动功能(在onCreate()之外)。此函数使用 for 循环将全局字符串变量更改5次。我想查看屏幕上显示的每个变量(即在TextView中)。我知道我必须使用 Runnable 处理程序,但是..

MainActivity(扩展活动)/ onCreate()

button1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View arg0) {
        handler.post(timedTask);
        Start();
    }
});

开始()会运行,但在完成之前屏幕上没有任何内容。

MainActivity(扩展活动)中:

private Runnable timedTask = new Runnable()
{
      @Override
      public void run()
      {
          textView1 = (TextView) findViewById(R.id.textView1);
          textView1.append(globalMessage);
          handler.postDelayed(this, 100);
      }};
MainActivity(扩展活动)/ Start():

for(int j = 0; j < 5; j++)
{
    ...
    globalMessage = message[j];
    ...
}

2 个答案:

答案 0 :(得分:2)

首先,您正在从不同的线程访问变量。您应该将其声明为volatile

所以你希望你的timedTask显示5个globalMessage值?

确保将timedTask与循环同步,以便在每次修改timedTask后执行。

for(int j = 0; j < 5; j++)
{
    ...
    globalMessage = message[j];
    ...// wait sometime here or make sure it is a long operation that is enough for synchronization
}

修改

您的handler.post可能无法立即开始运行。你可以自己开始运行:

(new Thread(timedTask)).start(); // instead of handler.post

或者以最简单的方式做到:只需在同一个帖子中更新for循环中的文本。

答案 1 :(得分:0)

我明白了!诀窍是代码从方法/函数添加到Runnable ,然后一切正常,每个文本都在更新当场。所以这段代码:

private Runnable timedTask = new Runnable()
{
      @Override
      public void run()
      {
          textView1 = (TextView) findViewById(R.id.textView1);
          textView1.append(globalMessage);
          handler.postDelayed(this, 100);
      }};

变为:

private Runnable timedTask = new Runnable()
{
    @Override
    public void run()
    {
        textView1 = (TextView) findViewById(R.id.textView1);
        for(int j = 0; j < 5; j++)
        {
        ...
        globalMessage = message[j];
        textView1.setText(globalMessage);
        ...
        }
    }
};

我改变了一些事情:

  1. 感谢 Tala ,我更改了handler.post(timedTask); Thread thread1 = new Thread(timedTask1);,然后thread1.start();或只更改了一行(new Thread(timedTask)).start();

  2. 我遇到了一些例外情况:

  3. android.view.ViewRoot $ CalledFromWrongThreadException :只有创建视图层次结构的原始线程才能触及其视图。

    这符合textView1.setText(globalMessage);textView1.append(globalMessage);以及该类型的更多方法和不在onCreate()中。如果您想在onCreate中使用它们,请阅读this回答,建议将该行替换为:

    runOnUiThread(new Runnable() {
        @Override
        public void run()
        {
            button1.append(globalMessage);
        }
    });
    

    你应该注意的另一个例外是java.lang。 NullPointerException 表示你应该初始化当前方法/ runnable / scope中的一些变量

    如果有人有疑问:请随时在这里发表评论!