上篇文章:子线程不显示Toast? 分析了子线程不显示Toast的原因,并通过Looper.prepare(); Looper.loop();
解决。这篇文章我们通过runOnUiThread()
解决,并分析原因。
本文:Android 12 api=32
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,"子线程",Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
}
//Activity.java
final Handler mHandler = new Handler();
...
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
//Handler.java
public final boolean post(@NonNull Runnable r) {
//这里通过getPostMessage() 把Runnable转为了一个Message对象
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
//Runnable 保存在Message的成员变量callback里面。
m.callback = r;
return m;
}
//Message.java
public final class Message implements Parcelable {
...
@UnsupportedAppUsage
/*package*/ Runnable callback;
...
}
总接一下:runOnUiThread()方法,是Activity的方法。它的入参Runnable最终被转化成了一个Message对象,然后就和sendMessage()方法的流程一样了。