创建Handler的线程必须有looper。
public Handler(Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } } mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }
looper = null 时,Handler构造器抛出异常。
再没有looper的工作线程中使用toast
public class ToastActivity extends AppCompatActivity implements View.OnClickListener { private View mBtn1; private Thread mThread = new MyThread(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toast); mBtn1 = findViewById(R.id.toast); mBtn1.setOnClickListener(this); } @Override public void onClick(View v) { mThread.start(); } public void logs(String text) { android.util.Log.i("jue","HandlerThreadActivity -> " + text); } @Override protected void onDestroy() { super.onDestroy(); } public class MyThread extends Thread { @Override public void run() { Toast.makeText(ToastActivity.this, "MyThread toast", Toast.LENGTH_SHORT).show(); } } }
发生了异常
给工作线程添加looper之后。
package com.jue.testservice1; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Toast; /** * Created by jue on 2016/11/18. */ public class ToastActivity extends AppCompatActivity implements View.OnClickListener { private View mBtn1; private WorkingThreadHandler mHander; private Thread mThread = new MyThread(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toast); mBtn1 = findViewById(R.id.toast); mBtn1.setOnClickListener(this); mThread.start(); } @Override public void onClick(View v) { mHander.sendEmptyMessage(100); } public void logs(String text) { android.util.Log.i("jue","HandlerThreadActivity -> " + text); } @Override protected void onDestroy() { super.onDestroy(); } public class MyThread extends Thread { @Override public void run() { Looper.prepare(); Looper looper = Looper.myLooper(); mHander = new WorkingThreadHandler(looper); Looper.loop(); } } public class WorkingThreadHandler extends Handler { public WorkingThreadHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { Toast.makeText(ToastActivity.this, "Working Thread toast", Toast.LENGTH_SHORT).show(); } } }
可以正常弹出toast。