ANR
Application No Response,应用程序无响应,因为在主线程中进行过多的耗时操作就会堵塞主线程从而造成ANR,产生的原因主要有三个Activity耗时超过5s,Broadcast Receiver超过10s,Service超过20s。
ANR的分析
通过Log和trace.txt
ANR的避免
将所有耗时操作,比如访问网络,Socket 通信,查询大量 SQL 语句,复杂逻辑计算等都放在子线程中去。比如通过AsyncTask执行。
AsyncTask
AsyncTask使用
使用AsyncTask主要重写这四个方法:
1. onPreExecute开始执行前的准备工作
2. doInbackground执行耗时操作
3. onProgressUpdate更新界面
4. onPostExecute执行完异步任务后的返回结果
AsyncTask解析
AsyncTask在初始化的时候,创建了一个Callable对象——mWorker和一个FutureTask对象——mFuture。
我们通过调用任务的excute()方法启动任务的时候,调用了executeOnExecutor()方法,executeOnExecutor()中,首先执行了onPreExecute()方法,之后执行了Excutor的excute()方法。(默认的Excutor是SerialExcutor,它可以保证任务执行的顺序将任务通过线程池执行。)
Excutor在执行excute()的时候,传入了mFuture,并执行其run()方法,在这其中启动了mWorker并进行了doInbackground()。
与此同时,mWorker的call()方法通过postResult(),对状态进行判断,并回调onCancelled(Result result)或者onPostExecute(Result result) 。
注意事项
AsyncTask不会随着Activity销毁,而是一直执行, 直到doInBackground()方法执行完毕。然后,如果 cancel(boolean)被调用, 那么onCancelled(Result result) 方法会被执行;否则,执行onPostExecute(Result result) 方法。所以,我们总是必须确保在销毁活动之前取消任务。