Android多線程之Handler

Handler多線程內部實現機制
這裏寫圖片描述
在Android開發中,我們經常會遇到這樣一種情況:在UI界面上進行某項操作後要執行一段很耗時的代碼,比如我們在界面上點擊了一個”下載“按鈕,那麼我們需要執行網絡請求,這是一個耗時操作,因爲不知道什麼時候才能完成。爲了保證不影響UI線程,所以我們會創建一個新的線程去執行我們的耗時的代碼。當我們的耗時操作完成時,我們需要更新UI界面以告知用戶操作完成了。

注意一下的Handler寫法會導致內存泄漏!!!!!!!!!!:

package com.example.kaifaceshi;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {
    private TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         tv=(TextView) findViewById(R.id.tv);
    }
        //handler登場!!!
        Handler h=new Handler() {

            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                super.handleMessage(msg);
                switch (msg.what) {
                case 100:

                    tv.setText("下載完成!");
                    break;

                }
            }

        };
    public void button1(View v) {
        new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub

                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                //注意:不能再非主線程內調用UI控件
                //發送一個空消息
                h.sendEmptyMessage(100);
                //獲取一個消息對象
                Message msg=h.obtainMessage();
                msg.obj="hello";
                msg.what=100;
                h.sendMessage(msg);
                //在指定時間發送
                h.sendEmptyMessageAtTime(100,System.currentTimeMillis()+300);
                //延遲發送
                h.sendEmptyMessageDelayed(100,200);

            }

        }).start();
    }
}

正確標準的寫法應該是:!!!!!!!!!!!!!!!

package com.example.kaifaceshi;

import java.lang.ref.WeakReference;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
/*
 * 總之Handler導致內存泄漏的原因就是:
 * 主Activity已經退出了,Handler依然引用着主Activity的資源,以導致內存泄漏
 */
public class MainActivity extends Activity {
    private static TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         tv=(TextView) findViewById(R.id.tv);
    }

    myHandler myHandler=new myHandler(this);
        //**************************
            static  class  myHandler extends Handler{
                    WeakReference<MainActivity> weak;
                    public myHandler (MainActivity Activity) {
                        weak=new WeakReference<MainActivity>(Activity);
                    }

                    @Override
                    public void handleMessage(Message msg) {
                        // TODO Auto-generated method stub
                        super.handleMessage(msg);
                        MainActivity activity=weak.get();
                        if(activity!=null) {
                            TextView v=(TextView) activity.findViewById(R.id.tv);
                            v.setText("下載完成!");
                        }

                    }

                }
                //**************************
}
發佈了140 篇原創文章 · 獲贊 42 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章