在run()中,如何在不崩溃的情况下调用方法(Java / Android)



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

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应用程序执行此操作,如果有帮助的话。我尝试过寻找答案,但是当涉及到处理线程的正确方法时,我感到非常迷茫。

你需要一个像这样的可运行/处理程序:

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

然后更改

potatoDisp();

自:

runOnUiThread(potatoRun);

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

您可能会

在后台更新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();
        }
    });
   }
}

这样的事情应该有效。

问题是您正在尝试在主 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();
            }
        }
    }
}

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

相关内容

最新更新