HandlerThread的用法與自定義HandlerThread(2)
阿新 • • 發佈:2019-02-13
自定義HandlerThread
(其實HandlerThread本身也沒有多少程式碼,不到200的程式碼很容易看完的,但是裡面所使用的類還要繼續往下看,然後就沒有然後了)
介面
介面和使用方法在上一節已經放出
簡單的自定義
class MyLooperThread extends Thread implements Handler.Callback {
public Looper looper = null;
public Looper getLooper() {
//下面的程式碼是是從HandlerThread抄來的————標記1
/* synchronized (this) {
while (isAlive() && looper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}*/
return looper;
}
@Override
public void run() {
Looper.prepare();
looper = Looper.myLooper();
Looper.loop();
handler.sendEmptyMessage(3);
}
@Override
public boolean handleMessage(Message msg) {
handler.sendEmptyMessage(1);
return false;
}
}
其實裡面很簡單,Callback依舊可以沒有
Looper.prepare();
looper = Looper.myLooper();
Looper.loop();
裡面的順序不能搞錯只有先prepare才能通過myLooper獲取,一旦進入loop迴圈後面的程式碼就無法執行
handler.sendEmptyMessage(3);
只有當looper.quit()後loop()方法後面的程式碼才能執行
另外在標記1的地方當handlerThread在start()後無法立即獲取(有一些ms單位的時間吧),這裡通過幾個button來觸發獲取looper的事件
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Handler handler1 = new Handler(myLooper.getLooper(), myLooper);
//執行在MyLooperThread裡面的looper
handler1.sendEmptyMessage(1);
}
});
話說原始碼是怎麼設計的呢?
就是上面標記的部分的那段程式碼
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
一個wait就讓UI執行緒ANR了,
然後在run裡面
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
好了一個notifyAll又讓所有等待該執行緒的執行緒(Ui執行緒)執行起來了,不得不說Ui執行緒有那麼點時間是延遲的。(說錯請噴)
完整程式碼
(內網不能傳檔案,只能粘了)介面是在上一節有的,之貼上2個Activity的程式碼了
主Activity程式碼:TestHandlerActivity
package com.holdfoot.looper;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.TextView;
import java.util.Random;
public class TestHandlerActivity extends AppCompatActivity {
private Button btn2, btn_start, btn;
private TextView tv, tv1;
private MyHandlerThread handlerThread;
private Handler handler, handlerUi;
private int i;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("onCreate CurrentThread=" + Thread.currentThread().getName());
btn2 = (Button) findViewById(R.id.btn2);
btn_start = (Button) findViewById(R.id.btn_start);
btn = (Button) findViewById(R.id.btn);
tv = (TextView) findViewById(R.id.tv);
tv1 = (TextView) findViewById(R.id.tv1);
//
handlerThread = new MyHandlerThread("myHandler");
handlerThread.start();
handler = new Handler(handlerThread.getLooper(), handlerThread);
handlerUi = new Handler() {
@Override
public void handleMessage(Message msg) {
tv.setText("msg.what=" + msg.what);
super.handleMessage(msg);
}
};
MyRunnable runnable=new MyRunnable();
handler.postDelayed(runnable,500);
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.sendEmptyMessage(1);//handler——>handlerThread——>handlerUi
}
});
btn_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(TestHandlerActivity.this, LooperThreadActivity.class));
}
});
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tv1.setText("每個應用通常都有不止一個執行緒,無論是網路通訊還是後臺服務," +
"這樣就需要大量的建立執行緒,所以乾脆google就直接建立了HandlerThread," +
"通過該Thread人們可以將自己的程式執行在裡面而不必每次都建立執行緒," +
"正是由於該Thread裡面的Looper才使得不用建立多個Thread,而讓每個Thread都能執行到," +
"說白了類似執行緒池的概念,但只有一個執行緒,一個執行緒包含一個任務池");
}
});
}
class MyRunnable implements Runnable{
@Override
public void run() {
handlerUi.sendEmptyMessage(i);
i=i+2;
handler.postDelayed(MyRunnable.this,1000);
}
}
@Override
protected void onDestroy() {
handlerThread.quit();
super.onDestroy();
}
private class MyHandlerThread extends HandlerThread implements Handler.Callback {
public MyHandlerThread(String name) {
super(name);
}
@Override
public boolean handleMessage(Message msg) {
System.out.println("handleMessage CurrentThread=" + Thread.currentThread().getName());
handlerUi.sendEmptyMessage(i);
i=i+10;
return false;
}
@Override
protected void onLooperPrepared() {
super.onLooperPrepared();
}
}
}
LooperThreadActivity
package com.holdfoot.looper;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class LooperThreadActivity extends AppCompatActivity {
private Handler handler;
private TextView tv;
private Button btn, btn1, btn0;
private MyLooperThread myLooper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_looper_thread);
tv = (TextView) findViewById(R.id.tv);
btn = (Button) findViewById(R.id.btn);
btn1 = (Button) findViewById(R.id.btn1);
btn0 = (Button) findViewById(R.id.btn0);
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
tv.setText("在looper裡面接受到了");
break;
case 3:
tv.setText("looper.quit()之後的的動作");
break;
}
super.handleMessage(msg);
}
};
btn0.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myLooper = new MyLooperThread();
myLooper.start();
}
});
/* if(myLooper.getLooper()==null){
Log.d("tag","====null");
}
if(myLooper.getObj()==null){
Log.d("tag","obj==null");
}
*/
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Handler handler1 = new Handler(myLooper.getLooper(), myLooper);//執行在MyLooperThread裡面的looper
handler1.sendEmptyMessage(1);
}
});
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myLooper.getLooper().quit();
}
});
}
class MyLooperThread extends Thread implements Handler.Callback {
public Looper looper = null;
public Handler mHandler = null;
public Looper getLooper() {
/* synchronized (this) {
while (isAlive() && looper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}*/
return looper;
}
@Override
public void run() {
Looper.prepare();
looper = Looper.myLooper();
Looper.loop();
handler.sendEmptyMessage(3);
}
@Override
public boolean handleMessage(Message msg) {
handler.sendEmptyMessage(1);
return false;
}
}
@Override
protected void onDestroy() {
if (myLooper != null) {
myLooper.getLooper().quit();
}
super.onDestroy();
}
}