android多線程handler+runOnUithread+view.post+handler.post

listview 可以暫時告一段落了。。。

   下面說說android的多線程機制,講到多線程,就可以說道android有名的ANR(Application Not Responding)既應用程序未響應,觸發ANR的條件大致有兩個:1、在activity中超過5秒的時間未能響應下一個事件。2、BroadcastReceive超過10秒,這兩個條件都會觸發ANR。

   下面模擬一個activity的ANR

protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button1).setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                try
                {
                    Thread.sleep(10000);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        });
    }

   運行效果:

               未觸發:

                         觸發後:


當用戶使用時 出現這樣的體驗,可想而知會很蛋疼的。。。

有人就會問 爲什麼會有ANR這樣的機制。

其實android系統中所有的UI顯示都是在main線程中執行的,如果線程中有耗時操作時,線程中的其他UI組件就會等耗時結束時才能開始響應,所以爲了避免這樣的情況,android用handler將耗時操作放到子線程中執行,當結束時,將耗時操作的結果發回給主線程,所以這裏又要引入線程間通信的概念


額(⊙o⊙)… 到這裏感覺 新概念越寫越多了。。。。  沒事 慢慢解決麼。。。

這麼說感覺線程間通訊 很蛋疼 其實 也就調用一個方法而已。。。。

嘿嘿


不多說了 看代碼先

private Handler mHandler = new Handler()
{
    //參數:Message相當於一種信息的載體,可以將子線程的數據傳到主線程中,也就是所謂的線程間通信了。。。
    public void handleMessage(android.os.Message msg)
    {//該方法在主線程中執行,不信的話可以log的。。。
        String result = (String) msg.obj;//從主線程傳來的數據    
        switch (msg.what)//what用於標記誰傳來的信息
        {
        case 1:
            mTextView1.setText(result);//做UI組件的設置必須在主線程否則會報錯的。。。
            break;
        case 2:
            mTextView2.setText(result);
            break;
        default:
            break;
        }
    }
};
private TextView mTextView1;
private TextView mTextView2;
@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mTextView1 = (TextView) findViewById(R.id.textView1);
    mTextView2 = (TextView) findViewById(R.id.textView2);
    Button button1 = (Button) findViewById(R.id.button1);
    button1.setOnClickListener(listener);
    Button button2 = (Button) findViewById(R.id.button2);
    button2.setOnClickListener(listener);                
}
private OnClickListener listener = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            switch (v.getId())
            {
            case R.id.button1:
                new Thread()
                {
                    public void run()
                    {
                        // 模擬耗時操作
                        try
                        {
                            Thread.sleep(1000);
                        }
                        catch (InterruptedException e)
                        {
                            e.printStackTrace();
                        }
                        String result = "從網絡獲取的結果";
                        Message msg = new Message();
                        msg.what = 1;
                        msg.obj = result;
                        // 發送到main線程
                        mHandler.sendMessage(msg);
                        // textView.setText(result);
                    }
                }.start();
                Log.e("MainActivity", "button1");
                break;
            case R.id.button2:
                new Thread()
                {
                    public void run() {
                        // 模擬耗時操作
                        try
                        {
                            Thread.sleep(1000);
                        }
                        catch (InterruptedException e)
                        {
                            e.printStackTrace();
                        }
                        String result = "從數據庫獲取的結果";
                        Message msg = new Message();
                        msg.what = 2;
                        msg.obj = result;
                        // 發送到main線程
                        mHandler.sendMessage(msg);
                    }
                }.start();
                Log.e("MainActivity", "button2");
                break;
            default:
                break;
            }
        }
    };

我會把源代碼 附加到文章的 佈局文件 就不寫了,佔地方。。。

運行結果:


handler 差不多就這些了。。。代碼的項目超過2mb 了 我放到51cto的網盤裏了

鏈接:handler



下面講講 post,其實view.post和handle.post這兩個方法差不多,都是在post方法中傳入一個實現了Runnable接口的對象,在這個對象的run方法中實現


private TextView mTextView;
    private Button mButton;
    class Listener implements OnClickListener
    {
        @Override
        public void onClick(View v)
        {
            switch (v.getId())
            {
            case R.id.button1:
                download();
                break;
            default:
                break;
            }
        }
    }
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mButton = (Button) findViewById(R.id.button1);
        mButton.setOnClickListener(new Listener());
    }
    public void download()
    {
        new PlayThread().start();//開啓子線程
    }
    class PlayThread extends Thread
    {
        @Override
        public void run()
        {// 這是子線程
            try
            {
                Thread.sleep(2000);//模擬從網絡下載數據的耗時操作
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
                                                                                                                                                                                        
            mButton.post(new Runnable()//這裏用的是view的post方法
            {//這裏的內容將在主線程中顯示
                @Override
                public void run()
                {
                    mTextView.setText("yes 獲取到數據了~~~");
                }
            });
        }
    }


runOnUiThread(Runnable action)方法和handler.post(Runnable action)方法,這兩個方法的用法跟view.post(Runnable action)方法的用法一樣

runOnUiThread(Runnable action)是activity的方法,這裏的Runnable同樣是運行在主線程中的

handler.post(Runnable action)是handler中的方法,大同小異,當然如果大家能告訴我這之間的區別我也會洗耳恭聽的,相互學習麼,謝謝啦。。。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章