写点什么

备战秋招 - 阿里巴巴面试真题:- 给你一个 Demo- 你如何快速定位 ANR?

用户头像
Android架构
关注
发布于: 刚刚

如果开发机器上出现 ANR 问题时,系统会生成一个 traces.txt 的文件放在/data/anr 下,最新的 ANR 信息在最开始部分。通过 adb 命令将其导出到本地,输入以下字符:


$adb pull data/anr/traces.txt .


####2.供选的优化 ANR 问题的方式:


1)为了执行一个长时间的耗时操作而创建一个工作线程最方便高效的方式是使用 AsyncTask,只需要继承 AsyncTask 并实现 doInBackground()方法来执行任务即可。为了把任务执行的进度呈现给用户,你可以执行 publishProgress()方法,这个方法会触发 onProgressUpdate()的回调方法。在 onProgressUpdate()的回调方法中(它执行在 UI 线程),你可以执行通知用户进度的操作,例如:


private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {// Do the long-running work in hereprotected Long doInBackground(URL... urls) {int count = urls.length;long totalSize = 0;for (int i = 0; i < count; i++) {totalSize += Downloader.downloadFile(urls[i]);publishProgress((int) ((i / (float) count) * 100));// Escape early if cancel() is calledif (isCancelled()) break;}return totalSize;}


// This is called each time you call publishProgress()protected void onProgressUpdate(Integer... progress) {setProgressPercent(progress[0]);}


// This is called when doInBackground() is finishedprotected void onPostExecute(Long result) {showNotification("Downloaded " + result + " bytes");}


2)如果你实现了 Thread 或者 HandlerThread,请确保你的 UI 线程不会因为等待工作线程的某个任务而去执行 Thread.wait()或者 Thread.sleep()。UI 线程不应该去等待工作线程完成某个任务,你的 UI 线程应该提供一个 Handler 给其他工作线程,这样工作线程能够通过这个 Handler 在任务结束的时候通知 UI 线程。例如:


继承 Thread 类


new Thread(new Runnable() {@Overridepublic void run() {/**耗时操作/handler.post(new Runnable() {@Overridepublic void run() {/*更新 UI*/}});}}).start();


实现 Runnable 接口


class PrimeRun implements Runnable {long minPrime;PrimeRun(long minPrime) {this.minPrime = minPrime;}


public void run() {// compute primes larger than minPrime. . .}}


PrimeRun p = new PrimeRun(143);new Thread(p).start();


使用 HandlerThread


// 启动一个名为 new_thread 的子线程 HandlerThread thread = new HandlerThread("new_thread");thread.start();


// 取 new_thread 赋值给 ServiceHandlerprivate ServiceHandler mServiceHandler;mServiceLooper = thread.getLooper();mServiceHandler = new ServiceHandler(mServiceLooper);


private final class ServiceHandler extends Handler {public ServiceHandler(Looper looper) {super(looper);}


@Overridepublic void handleMessage(Message msg) {//默认 Handler 的 handleMessage 方法是运


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


行在主线程中的,如果传入一个工作线程的 Looper,则改变 HandleMessage 方法执行的所在线程}}


3)开发在日常的开发过程中使用 Thread 或者 HandlerThread,可以尝试调用 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)设置较低的优先级,否则仍然会降低程序响应,因为默认 Thread 的优先级和主线程相同。


4)Activity 的 onCreate 和 onResume 回调中尽量避免耗时的代码,应该尽可能的做比较少的事情,其实,任何执行在 UI 线程中的方法都应该尽可能简短快速。类似网络或者 DB 操作等可能长时间执行的操作,或者是类似调整 bitmap 大小等需要长时间计算的操作,都应该执行在工作线程中。


5)BroadcastReceiver 中 onReceive 代码也要尽量减少耗时。如果必须在 onReceive 方法中执行耗时操作,建议使用 IntentService 进行处理,IntentService 集开启线程和自动关闭服务两种功能于一身,本身非常灵活。


@Overridepublic void onReceive(Context context, Intent intent) {// This is a long-running operationBubbleSort.sort(data);}//上面的代码在 onReceive 方法中执行了耗时操作


@Overridepublic void onReceive(Context context, Intent intent) {// The task now runs on a worker thread.Intent intentService = new Intent(context, MyIntentService.class);context.startService(intentService);}


public class MyIntentService extends IntentService {@Override

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
备战秋招-阿里巴巴面试真题:-给你一个Demo-你如何快速定位ANR?