线程冻结UI



我有这个按钮,当点击它时会调用thead来更新用户界面:

averageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Testing().execute();
}
});

该方法被执行,但它会冻结UI 10秒钟。每次调用averageMiles.append(mile(方法时,我都想更新UI。

class Testing extends AsyncTask<Void, Void, Void> {
@Override
protected void onPostExecute(Void unused) {
int x = 0;
while (true) {
if (x == 10) {
break;
}
ArrayList<Double> milesList = new ArrayList<>();

if (x == 0) {
averageMiles.setText("mph: ");
}
String mile = milesValue.getText().toString();
if (!isNum(mile)) {
continue;
}
averageMiles.append(mile);
milesList.add(Double.valueOf(mile.trim()));
x++;
if (x == 10) {
averageMiles.append("nAverage: " + getAverage(milesList));
return ;
} else {
averageMiles.append(", ");
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

使用官方oracle和android开发者文档中的ThreadPool执行器

Oracle文档-java.util.concurrent.ThreadPoolExecutor
Android文档-java.til.concurrent.ThreadPoolExecutor

正如您所指定的,您使用的是java,上面两个文档是谷歌推荐的,如下所示用于AsyncTask

此类在API 30级中已被弃用。请改用标准的java.util.concurrent或Kotlin并发实用程序。

最终目标是android说,如果你想更新UI,只需将runOnUiThread与一个新的可运行程序一起使用即可。你更新UI,这意味着对于每个UI更新,你可能会创建新的短期线程,该线程只更新UI,线程完成并垃圾回收

示例代码

public class MainActivity extends AppCompatActivity {
int count = 0;
Executor ex;
MyThread th;
class MyThread extends Thread implements Runnable {
private boolean running=false;
public void setRunning(boolean running) {
this.running = running;
}
@Override
public void run() {
while(running) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
count++;
TextView tv = findViewById(R.id.textView);
tv.setText(String.valueOf(count));
}
});
}
}
}
public void onStartClick(View view) {
th = new MyThread();
ex = Executors.newSingleThreadExecutor();
th.setRunning(true);
ex.execute(th);
}
public void onStopClick(View view) {
if(th!=null) {
th.setRunning(false);
}
}
}

该类的所有成员变量都应该只在runOnUiThread中访问,例如,如果您希望任何特定于线程的值只放在MyThread类中,count++count是MainActivity的变量

切勿尝试访问run()方法内的任何MainActivity变量

您也可以将MyThread编写为单独的类,并在启动线程之前设置类似于th.setRunning的值。

如果您希望在线程完成后进行回调,请使用一个接口,该接口将在MainActivity中为您提供回调方法

所以它只是核心java
我创建了一个带有接口的示例
并发执行器接口示例

最新更新