在run()中,如何在没有应用程序崩溃的情况下调用方法(Java / Android)?

时间:2014-01-14 19:48:20

标签: java android

我正在尝试制作一个简单的小程序,每秒递增一次数字。在这种情况下,我正在实现一个应该每秒循环一次的线程,并在每次循环时将“1”添加到“potato”。这可以正常工作,直到它返回显示方法potatoDisp()。由于某种原因,这会导致我的应用程序崩溃。从run()中删除potatoDisp()可以解决问题,但是当“马铃薯”增加时,显示不会更新。

public int potato = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    potatoDisp();
    start();
}

public void potatoDisp() {
    TextView text = (TextView) findViewById(R.id.textView1);
    text.setText("You currently have " + potato + " potatoes");
}

public void start() {
    Thread thread = new Thread(this);
    thread.start();
}

@Override
public void run() {
    while (true) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            return;
        }
        potato++;
        potatoDisp();
    }
}

我正在为Android应用做这个,如果有帮助的话。我已经尝试过寻找答案,但是当谈到正确的工作方式时,我很遗憾。

4 个答案:

答案 0 :(得分:2)

你需要一个像这样的runnable / handler:

private Runnable potatoRun = new Runnable() {
    @Override
    public void run () {
        potatoDisp();
    }
};

然后改变

potatoDisp();

为:

runOnUiThread(potatoRun);

当您不在UI线程上时,无法更新视图。

答案 1 :(得分:0)

您可能在后台更新UI时遇到异常。由于potatoDisp();是从后台Thread调用的,但该函数会更新UI,因此会给您带来问题。您需要使用runOnUiThread()调用它。

 @Override
public void run() {
while (true) {
    try 
    {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        return;
    }
    potato++;
    runOnUiThread(new Runnable()
    {
        @Override
        public void run()
        {
           potatoDisp();
        }
    });
   }
}

这样的事情应该有效。

答案 2 :(得分:0)

问题是您正在尝试在主UI线程以外的线程上更新UI(调用text.setText(...))。

虽然我建议使用TimerTask而不是调用Thread.sleep(...),但有两种主要方法可以编辑当前代码以按预期工作。

- 使用Handler

定义一个Handler类,它将接受消息并根据需要更新您的UI。例如:

private final String POTATO_COUNT = "num_potatoes";

Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        int numPotatoes = msg.getData.getInt(POTATO_COUNT);
        mText.setText("You currently have " + numPotatoes + " potatoes");
    }
}

然后在您要调用处理程序以更新文本视图的代码中,无论您是否在主UI线程上,请执行以下操作:

Bundle bundle = new Bundle();
bundle.putInt(POTATO_COUNT, potato);

Message msg = new Message();
msg.setData(bundle);
handler.sendMessage(msg);

- 致电runOnUiThread(...)

@Override
public void run() {
    while (true) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            return;
        }
        potato++;
        runOnUiThread(new Runnable() 
        {
            public void run() 
            {
                potatoDisp();
            }
        }
    }
}

答案 3 :(得分:0)

我认为您应该使用Async Task从线程更新UI:http://developer.android.com/reference/android/os/AsyncTask.html