handler初体验
多线程与异步:多个线程的开发,异步是说不要在主线程中开发
Android程序启动规律:启动应用----》启动Application----- 》启动进程----》进程中new一个主线程(UI线程,负责控件+事件分发)----》做耗时操作如网络请求时,创建另外一个线程去做----》别人做完后,应该通知我,涉及线程之间的通信
handler能够实现:线程之间的通信;跨进程通信(用到message)
- 定时执行Message和MessageQueue
- 在不同线程中执行
Message、MessageQueue、Looper
Message:2个整形值、1个Object
MessageQueue:Message的队列
Looper:消息泵
Looper:
-
消息队列MessageQueue的管理者
-
Looper.prepare() 每一个Looper对象和一个线程关联
-
Looper.myLooper()可以获得当前线程的Looper对象
-
Looper从MessageQueue里取出Message
-
交给Handler的handleMessage进行处理
-
调用Message.recycle()将其放入Message Pool中
Handler:
Message message = mTestHandler.obtainMessage();
mTestHandler.sendMessageDelayed(message, 1000);
mTestHandler.postDelayed(new Runnable() {
@Override
public void run() {
}
},1000); // 延时1s执行
每隔1s倒计时从10到0
通过弱引用,避免内存泄漏:
package com.jsc4.aboutactivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.widget.HeaderViewListAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import java.lang.ref.WeakReference;
public class HandlerButtonActivity extends AppCompatActivity {
private static final int MESSAGE_CODE = 888888;
private TextView mTextView;
private TestHandler mTestHandler = new TestHandler(this);
public TextView getTextView() {
return mTextView;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_button);
mTextView = findViewById(R.id.handler_text_view);
// 发送消息
Message message = mTestHandler.obtainMessage();
message.arg1 = 0;
message.arg2 = 1;
message.what = MESSAGE_CODE;
message.obj = 10000;
mTestHandler.sendMessageDelayed(message, 1000);
}
public class TestHandler extends Handler{
// 弱引用
public final WeakReference<HandlerButtonActivity> mHandlerButtonActivityWeakReference;
public TestHandler(HandlerButtonActivity activity){
mHandlerButtonActivityWeakReference = new WeakReference<HandlerButtonActivity>(activity);
}
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
HandlerButtonActivity handlerButtonActivity = mHandlerButtonActivityWeakReference.get();
// 接收消息
switch (msg.what){
case MESSAGE_CODE:
int value = (int) msg.obj;
handlerButtonActivity.getTextView().setText(String.valueOf(value/1000));
msg = Message.obtain();
msg.arg1 = 0;
msg.arg2 = 1;
msg.what = MESSAGE_CODE;
msg.obj = value - 1000;
if(value > 0){
sendMessageDelayed(msg, 1000);
}
break;
}
}
}
}