Main/UI Thread && Worker Thread
一般情況下,Worker線程不能直接更新主線程的設(shè)置(例如textview.settext()),否則會(huì)報(bào)錯(cuò)。
若要更新,一般用到以下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的靜態(tài)方法來創(chuàng)建,一般有三種:
- 單線程 :<code>Executors.newSingleThreadExecutor()</code>;
- 固定數(shù)量線程 :<code>Executors.newFixedThreadPool()</code>;
- 動(dòng)態(tài)線程 :<code>Executors.newCachedThreadPool()</code>;
- 定時(shí)線程:<code>Executors.newScheduleThreadPool()</code>;
這里我們用固定幾個(gè)線程來應(yīng)用,使用方法是創(chuàng)建<code>ExecutorService</code>對(duì)象,然后執(zhí)行<code>submit(r)</code>可以發(fā)起一個(gè)<code>Runnable</code>對(duì)象。
用線程池來管理的好處是,可以保證系統(tǒng)穩(wěn)定運(yùn)行,適用與有大量線程,高工作量的情景下使用,假如要展示1000張圖片如果創(chuàng)建1000個(gè)線程去加載,保證系統(tǒng)會(huì)死掉。用線程池就可以避免這個(gè)問題,可以用幾個(gè)線程輪流執(zhí)行,幾個(gè)一組,執(zhí)行完的線程不直接回收而是等待下次執(zhí)行,這樣對(duì)系統(tǒng)的開銷就可以減小不少。
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("當(dāng)前線程程:",""+Thread.currentThread().getName());
try {
final Drawable drawable = Drawable.createFromStream(new URL(url).openStream(), "image.gif");
mHandler.post(new Runnable(){
@Override
public void run() {
//這將在主線程運(yùn)行
((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(drawable);
}
});
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}