1. UI线程需要在主线程中进行操作,否则会影响线程安全
2.若在Adapter中的getView方法进行耗时操作,会影响listView滑动效果
3.Handler:线程中实现切换机制的线程类
Looper:每个线程均有的消息循环
Looper.getMainLooper(); 主线程中的循环 Looper.myLooper();当前线程的循环 若两个一致,则当前线程为主线程不是后台线程。
activity.this.runOnUiThread(new Runnable(){}); 强制切换到主线程中
在内部类里面的handler对象需要采用final形式
public void onClick(View v){ final Handler handler = new Handler(); final Runnable handlerTask = new Runnable(){ public void run(){ } }; Runnable task = new Runnable(){ public void run(){ handler.post(handlerTask); } }; final Thread t= new Thread(task); t.start(); }在handleMessage中,通过msg.what判断message 的类。 sendMessage和handleMessage的用法。
public void onButtonClick(View v){
final Handler handler = new Handler(){
public void handleMessage(Message msg){
String tost="None";
switch(msg.what){
case 0:
tost="--"+msg.obj;
break;
}
MainActivity.this.makeToast(toast);
}
};
Thread t = new Thread(new Runnable()){
public void run(){
Message msg0= Message.obtain(handler,0,"参数0");
handler.sendMessage(msg0);
}
});
t.start();
}
handler线程切换:public final boolean post(Runnable r)
a,在UI线程中创建handler b,手动创建looper
handlerThread 是thread子类,自动创建Looper
取消消息: public final void removeCallbacks(Runnable r )
Looper的退出: handlerThread.quit();
消息队列中全部的等待消息均退出,包括原先在消息队列但是未被处理的消息
handlerThread.quitSafely();若当前消息结束,后续等待着的消息可以立刻执行,并不会移除到消息队列外
public void onButtonClick(View v){ final handlerThread outerThread = new handlerThread("HandlerThread"); outerThread.start(); final Handler handler = new Handler(outerThread.getLopper()); Thread t = new Thread (new Runnable(){ public void run(){ handler.postDelayed(new Runnable(){ public void run(){ SecondActivity.this.makeToast("postDelayed 消息") } },1000); handler.post(new Runnable(){ public void run(){ outerThread.quit(); String msg="HandlerThread Loop 退出" SecondActivity.this.makeToast } }); } }); t.start(); }
主线程默认存在Looper,后台线程Looper可能未被创建。MessageQueue属于主线程的Looper
public class FirstActivity extends AppCompatActivity{ //当handler不为静态的或者是弱引用会造成内存泄漏 private Handler mHandler = new Handler(){ public void handleMessage(Message msg){ //普通内部类对外部类进行引用获取到activity Toast.makeText(FirstActivity.this,"消息来啦",Toast.LENGTH_SHORT).show(); } }; protected void onCreat(Bundle saveInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_first); Message msg= Message.obtain(mHandler,1); mHandler.sendMessageAtTime(msg,SystemClock.uptimeMillis()+60000); } }
MessageQueue-> msg -> mHandler ->FirstActivity 这个activity无法被GC
自定义Handler
public class FirstActivity extends AppCompatActivity{ //静态内部类不存在对外部类的引用 private int mMessageWhat; private Handler mHandler = new MyHandler(this); private static class MyHandler extends Handler{ private weakReference<FirstActivity> mActivityRef; public MyHandler(FirstActivity activity){ mActivityRef=new WeakReference<FirstActivity>(activity); } public void handleMessage(Message msg){ if(mActivityRef.get()!=null){ Toast.makeText(mActivityRef.get(),"消息来啦",Toast.LENGTH_SHORT).show(); } } } protected void onCreat(Bundle saveInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_first); mMessageWhat=1; Message msg= Message.obtain(mHandler,mMessageWhat); mHandler.sendMessageAtTime(msg,SystemClock.uptimeMillis()+60000); } protected void onDestory(){ super.onDestory(); mHandler.removeMessages(mMessageWhat); } }