我的理解是,子线程要和主线程通讯,就需要Handler+Message-消息机制
案例一:倒计时Demo(子线程+Handler+Message)
package liudeli.async; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private TextView tvInfo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvInfo = findViewById(R.id.tv_info); } /** * 定义Handler */ private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.obj != null) { tvInfo.setText(msg.obj.toString()); return; } tvInfo.setText(msg.what + ""); } }; /** * 耗时操作不能在主线程 定义主线程 */ private class MyTimeing implements Runnable { @Override public void run() { for (int i = 10; i >= 0; i--) { // mHandler.obtainMessage(i); 这种线程池方式获取Message消耗小 Message message = mHandler.obtainMessage(i); // what 其实就是ID的意思,唯一标示 if (i <= 0) { // obj 是Object 什么类型都可以传递: 传递T类型,获取的时候就强转T类型 message.obj = "倒计时完成?"; } // 用Android提供的睡眠方法,其实是封装来Thread.sleep SystemClock.sleep(1000); // 从子线程 发送消息 到---> 主线程的handleMessage方法 mHandler.sendMessage(message); } } } /** * 执行倒计时 * @param view */ public void timeing(View view) { // 主线程被阻塞 5秒 未响应,系统就会自动报错 ANR Application Not Responding /** * Android系统中,ActivityManagerService(简称AMS) 和 WindowManagerService(简称WMS)会检测App的响应时间 * 如果App在特定时间无法响应屏幕触摸或键盘输入事件,或者特定事件没有处理完毕,就会出现ANR */ // 启动自行车来做耗时操作 new Thread(new MyTimeing()).start(); } }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center"> <TextView android:id="@+id/tv_info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="0000000" android:layout_gravity="center_vertical" android:textSize="20sp" android:layout_marginLeft="10dp" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="倒计时" android:onClick="timeing" android:layout_gravity="right" /> </LinearLayout> </RelativeLayout>
案例二:文字变化(Handler+Message)
package liudeli.async; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.TextView; public class MainActivity2 extends AppCompatActivity { private TextView tvInfo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); tvInfo = findViewById(R.id.tv_info); } private int count; /** * 定义Handler */ private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.obj == null) { return; } if (msg.what <= 7) { tvInfo.setText(msg.obj.toString() + ""); Message message = mHandler.obtainMessage(); message.what = count++; message.obj = "竟然渐渐清晰 想要说些什么 又不知从何说起" + count; mHandler.sendMessageDelayed(message, 900); } } }; /** * 执行文字变化 * @param view */ public void textChange(View view) { // mHandler.obtainMessage(i); 这种线程池方式获取Message消耗小 Message message = mHandler.obtainMessage(); message.what = 1; message.obj = "从那遥远海边 慢慢消失的你 本来模糊的脸"; // 从主线程 发送消息 到---> 主线程的handleMessage方法 mHandler.sendMessageDelayed(message, 800); count = 0; } }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center"> <TextView android:id="@+id/tv_info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Test" android:layout_gravity="center_vertical" android:textSize="20sp" android:layout_marginLeft="10dp" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="文字变化" android:onClick="textChange" android:layout_gravity="right" android:layout_marginTop="20dp" /> </LinearLayout> </RelativeLayout>