Android之线程回掉更新ui

时间:2023-03-09 14:30:58
Android之线程回掉更新ui

一:工作线程中的回掉更新UI

public class MainActivity extends AppCompatActivity {

    private int i;
private Callback mCallback;
private TextView textView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text);
mCallback = new Callback() {
@Override
public void callback(int i) {
textView.setText("i");
}
};
doWorkAsNewThread(5000,mCallback);
} /**
* 开启工作线程
* @param delayMs 延时,以便对比
* @param callback 回掉,更新Ui
*/
private void doWorkAsNewThread(final long delayMs, final Callback callback){
new Thread(){
@Override
public void run() {
super.run();
try {
Thread.sleep(delayMs);
} catch (InterruptedException e) {
e.printStackTrace();
}
do {
i++;
}while(i<100); callback.callback(i);
}
}.start();
} interface Callback{
void callback(int i);
}

可以看到5s后报错了:Only the original thread that created a view hierarchy can touch its views.

二:改造2,在线程里切换到UI线程回掉

private void doWorkAsNewThread(final long delayMs, final Callback callback){
new Thread(){
@Override
public void run() {
super.run();
try {
Thread.sleep(delayMs);
} catch (InterruptedException e) {
e.printStackTrace();
}
do {
i++;
}while(i<100);
textView.post(new Runnable() {
@Override
public void run() {
callback.callback(i);
}
});
}
}.start();
}

这样是可行的,没报错。直接在Callback中改也可以:

mCallback = new Callback() {
@Override
public void callback(final int i) {
textView.post(new Runnable() {
@Override
public void run() {
textView.setText(String.valueOf(i));
}
});
}
};

但是两边都有回掉的话,好像会有问题。

三:异步线程内,用handler去更新是无效的。

 new Handler().post(new Runnable() {
@Override
public void run() {
textView.setText(String.valueOf(i));
}
});

Can't create handler inside thread that has not called Looper.prepare()

加上loop一样还是其他线程。

Looper.prepare();
new Handler().post(new Runnable() {
@Override
public void run() {
textView.setText(String.valueOf(i));
}
});
Looper.loop();

四:回掉自行区分选择在哪个线程:

private void callbackOnWorkThread(final int i, final Callback callback){
Looper.prepare();
new Handler().post(new Runnable() {
@Override
public void run() {
callback.callback(i);
}
});
Looper.loop();
} private void callbackOnMainThread(final int i, final Callback callback){
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
callback.callback(i);
}
});
}