歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android線程模型

Android線程模型

日期:2017/3/1 11:15:50   编辑:Linux編程
當一個程序第一次啟動的時候,Android會啟動一個LINUX進程和一個主線程。默認的情況下,所有該程序的組件都將在該進程和線程中運行。同時,Android會為每個應用程序分配一個單獨的LINUX用戶。Android會勁量保留一個正在運行進程,只在內存資源出現不足時,Android會嘗試停止一些進程從而釋放足夠的資源給其他新的進程使用, 也能保證用戶正在訪問的當前進程有足夠的資源去及時的響應用戶的事件。Android會 根據進程中運行的組件類別以及組件的狀態來判斷該進程的重要性,Android會 首先停止那些不重要的進程。按照重要性從高到低一共有五個級別:

前台進程
前台進程是用戶當前正在使用的進程。只有一些前台進程可以在任何時候都存在。他們是最後一個被結束的,當內存低到根本連他們都不能運行的時候。一般來說, 在這種情況下,設備會進行內存調度,中止一些前台進程來保持對用戶交互的響應。

可見進程
可見進程不包含前台的組件但是會在屏幕上顯示一個可見的進程是的重要程度很高,除非前台進程需要獲取它的資源,不然不會被中止。

服務進程
運行著一個通過startService() 方法啟動的service,這個service不屬於上面提到的2種更高重要性的。service所在的進程雖然對用戶不是直接可見的,但是他們執行了用戶非常關注的任務(比如播放mp3,從網絡下載數據)。只要前台進程和可見進程有足夠的內存,系統不會 回收他們。

後台進程
運行著一個對用戶不可見的activity(調用過 onStop() 方法).這些進程對用戶體驗沒有直接的影響,可以在服務進程、可見進程、前台進 程需要內存的時候回收。通常,系統中會有很多不可見進程在運行,他們被保存在LRU (least recently used) 列表中,以便內存不足的時候被第一時間回收。如果一個activity正 確的執行了它的生命周期,關閉這個進程對於用戶體驗沒有太大的影響。

空進程
未運行任何程序組件。運行這些進程的唯一原因是作為一個緩存,縮短下次程序需要重新使用的啟動時間。系統經常中止這些進程,這樣可以調節程序緩存和系統緩 存的平衡。

Android 對進程的重要性評級的時候,選取它最高的級別。另外,當被另外的一個進程依賴的時候,某個進程的級別可能會增高。一個為其他進程服務的進程永遠不會比被服 務的進程重要級低。因為服務進程比後台activity進程重 要級高,因此一個要進行耗時工作的activity最好啟動一 個service來做這個工作,而不是開啟一個子進程――特別 是這個操作需要的時間比activity存在的時間還要長的時 候。例如,在後台播放音樂,向網上上傳攝像頭拍到的圖片,使用service可 以使進程最少獲取到“服務進程”級別的重要級,而不用考慮activity目 前是什麼狀態。broadcast receivers做費時的工作的時候,也應該啟用一個服務而不是開一個線程。

2單線程模型
當一個程序第一次啟動時,Android會同時啟動一個對應的 主線程(Main Thread),主線程主要負責處理與UI相關的事件,如:用戶的按鍵事件,用戶接觸屏幕的事件以及屏幕繪圖事 件,並把相關的事件分發到對應的組件進行處理。所以主線程通常又被叫做UI線 程。在開發Android應用時必須遵守單線程模型的原則: Android UI操作並不是線程安全的並且這些操作必須在UI線程中執行。

單線程模型會在沒有考慮到它的影響的情況下引起Android應用程序性能低下,因為 所有的任務都在同一個線程中執行,如果執行一些耗時的操作,如訪問網絡或查詢數據庫,會阻塞整個用戶界面。當在執行一些耗時的操作的時候,不能及時地分發 事件,包括用戶界面重繪事件。從用戶的角度來看,應用程序看上去像掛掉了。更糟糕的是,如果阻塞應用程序的時間過長(5秒鐘)Android會向用戶提示一些信息,即打開一個“應用程序沒有相應(application not responding)”ANR 的對話框。

其實單線程模型就是默認情況下android把所有操作都放在主線程也就是UI Thread線程中來執行 如果你想 O上邊那段不是說它會阻塞用戶界面嘛 那我可以另起一個線程來執行一些操作 沒錯你的想法非常good 。很給力。那麼接下來 你就會嘗試另起一個線程來 執行一些操作。OK 結果就有兩種可能 一:你在另外開啟的那個線程中執行了一些後台的操作 比如開啟一個服務啊。神馬的。那麼恭喜你 你成功了。 二:第二種可能結果就是 你會收到一個華麗的異常 。這個例子很簡單

java代碼:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/textview01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:id="@+id/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/textview01"
android:text="異常測試"
/>
<TextView
android:id="@+id/myTextView"
android:textSize="15pt"
android:layout_toRightOf="@id/myButton"
android:layout_alignTop="@id/myButton"
android:textColor="#FF0000"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

</RelativeLayout>

java代碼:

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class Activity01 extends Activity {
private Button myButton;
private TextView myTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myButton = (Button) findViewById(R.id.myButton);
myTextView = (TextView) findViewById(R.id.myTextView);
myButton.setOnClickListener(new MyButtonListener());
}
class MyButtonListener implements OnClickListener {
@Override
public void onClick(View v) {
new Thread() {
@Override
public void run() {
// 我們在這裡更新了UI 設置了TextView的值
myTextView.setText("張三");
}
}.start();
}
}
}

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 就是這樣一個異常 這個異常告訴我們不可以再子線程中更新UI元素 比如我們上邊那個例子設置了一個TextView的值。所有與UI相關的操作都不可以在子線程中執行都必須在UI線程中執行。這個異常大家以後可能會經常遇到多加注意就是了。

Copyright © Linux教程網 All Rights Reserved