前言:android
1.對Thread.sleep(long duration)的認知。
因爲CPU分配的每一個線程的時間片極爲短暫(通常爲幾十毫秒),因此,CPU經過不停地切換線程執行,這樣就給程序員一種錯覺,覺得多個線程是在同時執行。sleep就是正在執行的線程主動讓出CPU,CPU去執行其餘線程,在sleep指定的時間事後,CPU纔會回到這個線程上繼續往下執行.
2.對ANR的理解。程序員
ANR定義:網絡
Application Not Responding,意思是」應用沒有響應「
3.對耗時操做和Thread.sleep(long duration)的認知。
一般狀況下,某些同窗對耗時操做的理解就是執行了執行了必定耗時邏輯(好比,while循環或者進行了網絡請求之類操做)。認爲Thread.sleep(long duration)是讓出了當前線程的cpu執行權,至關於當前線程的休眠,因此不屬於耗時。
這樣理解比較狹隘,所謂耗時,即當前線程停滯不前,不在執行後面的邏輯,所以二者都能知足,只不過一個耗時操做把時間耗在了執行耗時邏輯,一個耗時把時間耗在了休眠上。正是基於此,因此你們纔會常用Thread.sleep(long duration)來模擬耗時操做。
正文:ide
之前個人理解就是 「在主線程作了耗時操做」就會引發ANR,如今我以爲我是錯誤的,爲何呢?
由於ANR的意思是應用沒有響應,可是耗時操做實際上 並不必定會致使沒有響應。post
我對沒有響應的理解是:測試
有人(事件或操做)發出了一個請求,可是主線程沒有對這我的進行反饋(多是沒時間、多是不想理、多是手被綁住了沒有辦法理你),這個叫沒有響應ui
下面舉個例子來驗證下。spa
public class MainActivity extends AppCompatActivity {.net
private static final String TAG = "MainActivity";
private TextView testText;線程
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
Button btnTest = findViewById(R.id.btn_test);
testText = findViewById(R.id.tv_test);
btnTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
testSleep();
}
});
}
public void testSleep() {
//todo:10s以後本應該進行更新ui操做,可是因爲此時主線程處於休眠狀態,所以待主線程結束休眠以後纔會進行更新ui操做
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Log.d(TAG, "準備更新text");
testText.setText("update btn text");
Log.d(TAG, "更新text完成");
}
}, 10000);
try {
Log.d(TAG, "準備sleep30秒");
Thread.sleep(30000);
Log.d(TAG, "sleep30秒完成");
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "first update");
testText.setText("This is the first update");
}
}
先看運行日誌:
這段代碼在 onCreate 中 sleep 了 30秒,而後更新testText,會出現 ANR 嗎?
答案是
可能會,也可能不會
不會出現ANR的狀況:
若是點擊了」測試按鈕「,以後的30s以內,咱們沒有進行手動觸摸操做(即沒有進行任何操做),則不會發生ANR,這是由於這段代碼裏面的sleep休眠了線程,代碼裏面的更新操做根本沒有在 sleep的時候被觸發(處於休眠狀態),也就沒有了發送請求的前提條件,因此並無發生ANR。
會出現ANR的狀況:
可是若是用戶手動進行了觸摸操做(好比點擊屏幕或者按返回鍵),至關於有一個請求的事件了,而主線程又被休眠了,超過了規定的時間就會觸發ANR提示。
如圖:
好了,你如今對ANR是否是有了進一步的認識呢。
補充:
在android裏面對致使ANR的耗時時常進行了常量定義
Android N 的 ANR時間
Service 超時
// How long we wait for a service to finish executing.
static final int SERVICE_TIMEOUT = 20*1000; // 前臺
// How long we wait for a service to finish executing.
static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10; // 後臺
Broadcast 超時
// How long we allow a receiver to run before giving up on it.
static final int BROADCAST_FG_TIMEOUT = 10*1000; // 前臺
static final int BROADCAST_BG_TIMEOUT = 60*1000; // 後臺
InputDispatching 超時
// How long we wait until we timeout on key dispatching.
static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
ontentProvider 超時
// How long we wait for an attached process to publish its content providers
// before we decide it must be hung.
static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
好了,至此完結,小夥伴若是有問題請留言