android入門 — 多線程(一)
阿新 • • 發佈:2017-05-22
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入門 — 多線程(一)