我有这个按钮,当点击它时会调用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
我创建了一个带有接口的示例
并发执行器接口示例