1. 程式人生 > >android入門 — 多線程(一)

android入門 — 多線程(一)

xtend 分享 調用 管理 ava 導致 ui線程 rec thread

技術分享

  android中的一些耗時操作,例如網絡請求,如果不能及時響應,就會導致主線程被阻塞,出現ANR,非常影響用戶體驗,所以一些耗時的操作,我們會想辦法放在子線程中去完成。

  android的UI操作並不是線程安全的,所以多個線程並發操作UI組件的時候,則可能導致線程安全問題。為了解決這個問題,android只允許UI線程修改UI組件。

  

public class MainActivity extends AppCompatActivity
{
    TextView textView;
    Button changeText;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        changeText = (Button)findViewById(R.id.btn);
        textView = (TextView)findViewById(R.id.textView);
        changeText.setOnClickListener(this);
    }

    public void change(View view)
    {
        switch (view.getId())
        {
            case R.id.btn:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText("被改變了");
                    }
                }).start();
                break;
            default:
                break;
        }
    }
}

  在xml中定義了一個按鈕和一個TextView,當點擊按鈕的時候,開啟子線程去更改TextView中的文字,但是在編譯的時候是無法通過的,因為不允許在子線程中直接對UI線程中組件進行操作。

  需要借用Handler來實現子線程更新UI組件的功能。

public class MainActivity extends AppCompatActivity
{

    private TextView textView;
    private Handler handler = new Handler()
    {
        //接收的是消息隊列中的msg
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case 0x0001:
                    int index = msg.arg1;
                    textView.setText(index + "");
                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView)findViewById(R.id.textView1);
    }

    public void changeNumber(View view)
    {
        switch (view.getId())
        {
            case R.id.btn:
                new Thread()
                {
                    public void run()
                    {
                        for(int i = 0; i < 10; i++)
                        {
                            Message msg = new Message();
                            //msg.what是必不可少的,需要用來做判定
                            msg.what = 0x0001;
                            msg.arg1 = i;
                            handler.sendMessage(msg);
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }.start();
                break;
        }
    }
}

  

MessageQueue消息隊列

  android采用的是MessageQueue機制保證線程間通信。

  MessageQueue是一個消息隊列,用來存放通過Handler發布的消息,Android在第一次啟動程序的時候會默認為UI線程創建一個關聯的消息隊列,用來管理程序的組件,如Activity、BroadcastReceiver、Service等。

Handler消息傳遞機制

  工作線程通過handler對象和主線程進行通信

  Handler對象所有工作都在主線程中執行

  Handler類需要實現handleMessage()方法,來處理消息隊列中取出的Message對象

  handleMessage()方法由主線程調用,可以在需要的時候更新UI線程,但是必須確保此方法快速完成,因為其他的UI操作會等待它完成才能執行

技術分享

  

技術分享

android入門 — 多線程(一)