(1)用戶態線程:(Linux)
由於內核並沒有對多線程進程的支持,因此,內核中隻有單線程進程的概念, 而多線程進程是通過一個和應用程序連接的函數庫實現的。由於內核沒有輕量 級進程(線程)的概念,因此它不能獨立的對之進行調度,而是由一個線程運 行庫來組織線程的調度,其主要工作在於在各個線程的棧之間調度。如果一個進程中的某一個線程調用瞭一個阻塞的系統調用,該進程就會被阻塞,當然該進程中的其他所有線程也同時被阻塞,因此UNIX使用瞭異步I/O機制。
這種機制主要的缺點在於在一個進程中的多個線程的調度中無法發揮多處理器的優勢(如上述的阻塞情況)。
其優點包括:
A (相對於進程操作而言)某些線程操作的系統消耗大大減少。比如,對屬於同一個進程的線程之間進行調度切換時不需要調用系統調用,因此將減少額 外的消耗,往往一個進程可以啟動上千個線程也沒有什麼問題。
B 用戶態線程的實現方式可以被定制或修改以適應特殊應用的要求。這對於多 媒體實時過程等尤其有用。另外,用戶態線程可以比核心態線程實現方法的默認情況支持更多的線程。
LINUX的線程庫有NPTL(Native POSIX Thread Library)和LinuxThreads。
\
(2)核心態線程(Window)
這種線程的實現方法允許不同進程中的線程按照同一相對優先調度方法進行調 度。這有利於發揮多處理器的並發優勢。
二、Handler、Looper、MessageQueue介紹
Handler用於異步消息處理,但是Handler自己並不會創建線程。一般Handler用於計劃任務和線程間的通信。
在後臺線程與UI線程的交互中最常用。原理是:系統啟動程序時,會自動為UI線程創建一個消息隊列,和用於管理這個消息隊列的Looper。在創建的後臺線程時,默認是不會創建Looper和消息隊列的(我們自己可以通過調用Looper.prepare()給後臺線程創建Looper和消息隊列)。
通過給Handler傳遞不同的Looper實現向不同的線程傳遞信息。Looper.getMainLooper()會獲得UI線程的Looper。(後面我們會用代碼實現)
三、Android多線程與界面交互的方法
1.Activity.runOnUIThread(Runnable)
2.View.post(Runnable),View.postDelay(Runnable,long)
3、Handler
4、AsyncTask
下面用一個工程實現瞭上面四種交互方法
public class MainActivity extends Activity {
private TextView txView;
private Button button;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i("RootyInfo", "oncreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txView=(TextView)findViewById(R.id.textView1);
button=(Button)findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//創建一個用於展示前三種後臺線程和UI線程交互的線程
new TestThread(MainActivity.this).start();
//創建一個用於展示AsyncTask實現交互的TestAsyncTask
new TestAsyncTask().execute("Test"," AsyncTask");
}
});
}
class TestAsyncTask extends AsyncTask<String, Integer, String>
{
//TestAsyncTask被後臺線程執行後,被UI線程被調用,一般用於初始化界面控件,如進度條
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
//doInBackground執行完後由UI線程調用,用於更新界面操作
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
txView.setText(result);
super.onPostExecute(result);
}
//在PreExcute執行後被啟動AysncTask的後臺線程調用,將結果返回給UI線程
@Override
protected String doInBackground(String… params) {
// TODO Auto-generated method stub
StringBuffer sb=new StringBuffer();
for (String string : params) {
sb.append(string);
}
return sb.toString();
}
}
//用於線程間通信的Handler
class TestHandler extends Handler
{
public TestHandler(Looper looper) {
super(looper);
// TODO Auto-generated constructor stub
}
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
System.out.println("123");
txView.setText((String)msg.getData().get("tag"));
super.handleMessage(msg);
}
}
//後臺線程類
class TestThread extends Thread
{
Activity activity;
public TestThread(Activity activity) {
this.activity = activity;
}
@Override
public void run() {
//下面代碼用來演示Activity.runOnUIThread(Runnable)方法的實現
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
txView.setText("Test runOnUIThread");
}
});
//下面代碼用來演示Activity.runOnUIThread(Runnable)方法的實現
txView.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
txView.setText("Test View.post(Runnable)");
}
});
//下面代碼用來演示Activity.runOnUIThread(Runnable)方法的實現
txView.postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
txView.setText("Test View.postDelay(Runnable,long)");
}
}, 1000);
//下面代碼用來演示Handler方法的實現
Message msg=new Message();
Bundle bundle=new Bundle();
bundle.putString("tag", "Test Handler");
msg.setData(bundle);
new TestHandler(Looper.getMainLooper()).sendMessage(msg);
super.run();
}
}
}