前言: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;
好了,至此完结,小伙伴若是有问题请留言