App里发生的最糟糕的事是弹出应用无响应”Application Not Responding” (ANR) 对话框.本课讲的是如何保持应用响应,避免ANR。
什么触发ANR
通常,系统会在应用无法对用户输入响应时显示ANR。比如,如果一个应用在I/O操作上阻塞了(频繁请求网络)UI线程,系统无法处理用户输入事件。或者,在UI线程中,app花了大量时间在构建复杂的类,或在游戏中计算下一个动作。保证这些操作高效是很重要的,但最高效的代码也需要花费时间。
在任何情况下,都不要在UI线程执行耗时任务,取而代之的是创建 一个工作线程,在这个线程里操作。这可以保持UI线程运行,阻止系统因为代码卡住而结束应用。
在Android里,Activity Manager和Window Manager系统服务监控着应用的响应能力。Android会在检测到以下情形中之一时,弹出ANR对话框:
1.未在5秒内对用户输入事件响应
2.BroadcastReceiver未在10秒内执行完
如何避免ANR
Android应用默认运行在单线程里,叫UI线程或主线程。这意味着,你的应用所有工作都在UI线程里,如果花费很长时间才能完成,会触发ANR,因为此时应用无法操控输入事件或广播。
因此,UI 线程里的任何方法都应该尽可能地做轻量的工作,特别是Activity在生命周期方法,像onCreate(),onResume().潜在的耗时操作,像网络,数据库,或昂贵的计算(像改变图片大小)应该在工作线程里完成(或者在数据库操作案例里,通过一个异步请求)。
最高效的方法是为耗时操作使用AsyncTask类创建工作线程。继承AsyncTask实现doInBackground()方法来执行工作。要发送进度给用户,调用 publishProgress(),会触发onProgressUpdate(),例子:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { // Do the long-running work in here protected 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 called if (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 finished protected void onPostExecute(Long result) { showNotification("Downloaded " + result + " bytes"); } }
执行这个工作线程,只需要创建一个实例,调用 execute():
new DownloadFilesTask().execute(url1, url2, url3);
尽管比AsyncTask更复杂,你可能还是想创建自己的线程或者HandlerThread类,如果这么做,你应该调用Process.setThreadPriority(THREAD_PRIORITY_BACKGROUND) 设置线程优先线为”background”.如果没有,线程仍然会拖慢应用,因为它跟UI线程优先级相同。
如果你实现Thread或HandlerThread,确保UI线程没有因为等待工作线程执行完而阻塞。不要调用Thread.wait()或Thread.sleep(),而是提供一个Handler,供任务执行完后回调。如此设计,UI线程会保持响应,避免出现ANR对话框。
特别强调BroadcastReceiver的执行时间,意味着你要:分散工作到后台线程里,像保存设置或者注册Notification。执行密集任务(intensive tasks),应该用IntentService。
提示:你可以用StrictMode帮你找到在UI线程上潜在的耗时操作
问题内容: 建议在HTML页面中使用表格(现在已经有了CSS)? 表格有什么用途?表具有哪些CSS所没有的功能? 问题答案: 一点都不。但是将表格用于表格数据。只是不要将它们用于一般布局。 但是,如果您显示表格数据(例如结果或什至是表格),请继续使用表格!
我正试图用tkinter编写一个Python GUI程序。 我想做两根线。一个使用main_form函数运行,以防止tkinter保持更新和循环(避免“无响应”)。 另一个,当按钮1(btn1)被单击时,使函数sci_thread()开始运行,并启动执行长时间代码main_scikit的thread2。 但是tkinter一直没有回应。 下面是我的代码:
理论上讲,总是可以到达嵌套在两个循环中的语句。 编译器不同意,并要求在循环之外使用语句。我想知道一种优雅的方法来优化这个方法,这超出了我目前的理解,我尝试的break实现似乎都不起作用。 附加的是来自赋值的一个方法,该方法生成随机整数,并返回循环遍历直到找到第二个随机整数为止的迭代,该迭代是在作为int参数传递给该方法的范围内生成的。
本文向大家介绍Android应用开发中WebView的常用方法笔记整理,包括了Android应用开发中WebView的常用方法笔记整理的使用技巧和注意事项,需要的朋友参考一下 基本使用 使用WebView通常是需要网络的,所以需要加上访问网络的权限 1.加载某个url的方法 需要注意的是不要省略前面的http://,省略的话,某些ROM中的WebView会加载失败 2.加载assets中的HTML
刚刚将一个应用程序从V12升级到V13-仅在帮助中进行文本更改。工作很好。 上传给开发人员。它不会发布新的APK,说: “无法发布此配置,原因如下:版本12未提供给任何设备配置:所有可能接收版本12的设备都将接收版本13。” 它在说什么?V12是针对40K+设备发布的,我刚刚对其他三个应用程序做了完全相同的事情,没有任何问题,但这一个不会有。 不知道这是什么意思。我能做的就是把它存为草稿。
问题内容: 我读到应该避免赞成和。我对弄乱Loop并没有信心,也没有完全理解Codex。 下面的代码是否使用?如果是,并且由于应该避免,那么您能建议一种不使用但仍然完成相同任务的方法吗? 此代码用于按随机或按价格对帖子进行排序。 。 使用此代码将链接A(随机)和链接B(价格)发布在我的菜单中。因此,网站的访问者只需单击链接即可对帖子进行排序。 问题答案: 我已经针对WPSE这个主题做了非常详细的解