Handler想到的

Handler我們經常使用,handler的消息機制更是差不多面試時的必問考點,今天我們來討論一下handler的內存泄露等問題,這個問題也算是老生常談了。不多說了,直接代碼,全部註釋裏面了

public class MainActivity extends Activity {

    //定義爲final虛擬機會使用內聯機制提升性能
    private final MyHandler myHandler=new MyHandler(this);
    private  int i=0;
    private TextView textView;

    private final MyAsyncTask  myAsyncTask=new MyAsyncTask();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView=(TextView)findViewById(R.id.content);

    }

     //asyncTask的用法
    private class  MyAsyncTask extends AsyncTask<Void,Void,Void>{

        @Override
        protected Void doInBackground(Void... params) {

            //模擬耗時任務
            try {

                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            return null;
        }


        @Override
        protected void onPostExecute(Void aVoid) {

            if(MainActivity.this.isFinishing()){

                return;
            }

            initViews();
        }
    }


    //防止handler內存泄露的標準寫法
    private static class  MyHandler extends Handler
    {

        //弱引用 GC想回收隨時回收
        private WeakReference<MainActivity>  weakReference;

        public MyHandler(MainActivity  activity) {

            weakReference=new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {


            if(weakReference.get()!=null){

                weakReference.get().initViews();

            }

        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        myHandler.removeCallbacksAndMessages(null);//移除所有待處理message

        //取消任務
        if (myAsyncTask!=null&&myAsyncTask.getStatus()!= AsyncTask.Status.FINISHED) {
            myAsyncTask.cancel(true);
        }
    }


    private void initViews(){

        textView.setText(i + "");

    }

    //想到的計時器
   //計時器方式1
    private void timer1(){

        new Thread(new Runnable() {
            @Override
            public void run() {


                while (true){


                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    i = (int) (Math.random() * 1000);
                    myHandler.sendEmptyMessage(0x11);

                }
            }
        }).start();


    }


    //計時器方式2
    private void timer2(){

        Timer timer=new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                //子線程
                i = (int) (Math.random() * 1000);

                myHandler.sendEmptyMessage(0x11);


            }
        }, 1000, 1000);

    }

    //計時器方式3
    private void timer3(){

        final Handler handler=new Handler();
        Runnable runnable=new Runnable() {
            @Override
            public void run() {
                //主線程

                i = (int) (Math.random() * 1000);
                initViews();

                handler.postDelayed(this,1000);

            }
        };
        handler.postDelayed(runnable,1000);


    }


}

其他

        /**
         * 內部也是調用handler的post(Runnable runnable) 最後調用handler的sentMessage方法
         */
        runOnUiThread(new Runnable() {
            @Override
            public void run() {

            }
        });

看源碼

    //如果當前線程不是ui線程,調用在ui線程中創建的handler的post方法,否則立即執行run方法
    public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else {
            action.run();
        }
    }
發佈了87 篇原創文章 · 獲贊 126 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章