Handler
1、簡介:
Android中主線程是不能進行耗時操作的,子線程是不能進行更新UI的。所以就有了handler,它的作用就是實現線程之間的通信。 handler整個流程中,主要有四個對象,handler,Message,MessageQueue,Looper。當應用創建的時候,就會在主線程中創建handler對象, 我們通過要傳送的消息保存到Message中,handler。post,handler通過調用sendMessage方法將Message發送到MessageQueue中,Looper對象就會不斷的調用loop()方法 不斷的從MessageQueue中取出Message交給handler進行處理。從而實現線程之間的通信。
2、Looper、MessageQueue、Message、Handler的關系
Looper:
每一個線程只有一個Looper,每個線程在初始化Looper之后,然后Looper會維護好該線程的消息隊列,用來存放Handler發送的Message,並處理消息隊列出隊的Message。它的特點是它跟它的線程是綁定的,處理消息也是在Looper所在的線程去處理,所以當我們在主線程創建Handler時,它就會跟主線程唯一的Looper綁定,從而我們使用Handler在子線程發消息時,最終也是在主線程處理,達到了異步的效果。
在主線程中,ActivityThread默認會把Looper初始化好,prepare以后,當前線程就會變成一個Looper線程。
MessageQueue:
MessageQueue是一個消息隊列,用來存放Handler發送的消息。每個線程最多只有一個MessageQueue。MessageQueue通常都是由Looper來管理,而主線程創建時,會創建一個默認的Looper對象,而Looper對象的創建,將自動創建一個MessageQueue。其他非主線程,不會自動創建Looper。
Message:
消息對象,就是MessageQueue里面存放的對象,一個MessageQueu可以包括多個Message。當我們需要發送一個Message時,我們一般不建議使用new Message()的形式來創建,更推薦使用Message.obtain()來獲取Message實例,因為在Message類里面定義了一個消息池,當消息池里存在未使用的消息時,便返回,如果沒有未使用的消息,則通過new的方式創建返回,所以使用Message.obtain()的方式來獲取實例可以大大減少當有大量Message對象而產生的垃圾回收問題。
Handler的主要用途
-
推送未來某個時間點將要執行的Message或者Runnable到消息隊列。
-
在子線程把需要在另一個線程執行的操作加入到消息隊列中去。
實例一:通過Handler配合Message或者Runnable實現倒計時
public class MainActivity extends AppCompatActivity {
private static final int UPDATE = 0x1;
private TextView mTv;
實列二:在子線程把需要在另一個線程執行的操作加入到消息隊列中去
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
public class Main2Activity extends AppCompatActivity implements View.OnClickListener {
private Button mLoad;
private Button mReset;
private ImageView mImageView;
