Main/UI Thread && Worker Thread
一般情況下,Worker線程不能直接更新主線程的設置(例如textview.settext()),否則會報錯。
若要更新,一般用到以下4種方法:
Activity runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)
-
new Handler(Looper.getMainLooper()).post
new Thread(new Runnable() { @Override public void run() { // 第一種 runOnUiThread(new Runnable() { @Override public void run() { mTextView.setText("……"); } }); // 第二種 mTextView.post(new Runnable() { @Override public void run() { mTextView.setText("……"); } }) ; // 第三種 mTextView.postDelayed(new Runnable() { @Override public void run() { mTextView.setText("……"); } },1000); // 第四種 new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { mTextView.setText("……"); } }); } }).start();
線程池
ExecutorServie 線程池,適合處理大量線程。
通過Executors的靜態方法來創建,一般有三種:
- 單線程 :<code>Executors.newSingleThreadExecutor()</code>;
- 固定數量線程 :<code>Executors.newFixedThreadPool()</code>;
- 動態線程 :<code>Executors.newCachedThreadPool()</code>;
- 定時線程:<code>Executors.newScheduleThreadPool()</code>;
這里我們用固定幾個線程來應用,使用方法是創建<code>ExecutorService</code>對象,然后執行<code>submit(r)</code>可以發起一個<code>Runnable</code>對象。
用線程池來管理的好處是,可以保證系統穩定運行,適用與有大量線程,高工作量的情景下使用,假如要展示1000張圖片如果創建1000個線程去加載,保證系統會死掉。用線程池就可以避免這個問題,可以用幾個線程輪流執行,幾個一組,執行完的線程不直接回收而是等待下次執行,這樣對系統的開銷就可以減小不少。
private ExecutorService service = Executors.newFixedThreadPool(5);
private void loadImagesByExecutors(final String url,final int id){
service.submit(new Runnable(){
@Override
public void run() {
Log.e("當前線程程:",""+Thread.currentThread().getName());
try {
final Drawable drawable = Drawable.createFromStream(new URL(url).openStream(), "image.gif");
mHandler.post(new Runnable(){
@Override
public void run() {
//這將在主線程運行
((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(drawable);
}
});
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}