很多新手开发程序的时候,或者将原来跑在Android 2.X上的程序迁移到Android 3.x以上的时候经常会莫名其妙的出现崩溃(Crash)。从我的经验来看,这里可能有很多原因,但是最重要也是最常见的一个,可能是因为你在UI线程中做了一个耗时的操作。

什么是UI线程?


UI线程的重要性和概念是每一个Android开发者都应该谙熟于心的。每次一个应用启动后,系统会为该进程创建一个叫做"main"的线程,即UI线程,或者主线程。这个线程主要是用来分发事件到应用里面的组件和控件上的,所以很重要,同时也是各个组件间交互的桥梁。例如,如果你按下了一个按钮,UI线程就会分发这个触摸事件到这个按钮控件上,然后设置它的状态,同时发出一个绘制按钮请求(比如按钮变成按下的模样)事件队列中,随后UI线程不断的从队列中取出这个事件来让系统绘制它。

这种单线程模型可能会导致糟糕的性能除非你合适的处理。因为UI线程几乎是处理任何正在进行的事件,所以如果你在UI线程里面做了一个诸如访问网络或者查询数据库之类的耗时操作,那么就会卡住UI线程使它不能处理别的事情,这就会造成卡住界面。因为事件分发不了了,界面也没法重绘了,也没法响应用户的操作了。从用户来看,似乎程序是不响应了。

对于这种情况,及时的反馈是重要的。研究表明0.1秒是用户感受是否有立即响应的极限时间。如果耗时比这个长那么用户即会感觉系统有点迟钝,即使是几分之一秒也是令人感觉不好的。更糟糕的情况是,如果UI线程被卡住超过5秒,Android系统会直接弹出一个对话框,即ANR(“application not responding”),随后即强制关闭这个程序。

为什么你的程序会崩溃(Crash)?


为什么很多原来跑在Android 2.X上没问题的程序迁移到Android 3.x或者Android4.x以上的时候经常会莫名其妙的出现崩溃(Crash)?这是因为Honeycomb(3.x)和ICS(4.x)版本以后对于检查是否在UI线程中做耗时操作这一禁忌更加严格了,即它会直接抛出异常。

比如,如果在Android 3.x以上的机器上跑的程序在UI线程中访问网络,则会直接抛出一个NetworkOnMainThreadException异常:

E/AndroidRuntime(673): java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.example/com.example.ExampleActivity}: android.os.NetworkOnMainThreadException

下面是Android Developer上对该异常的解释:

  • A NetworkOnMainThreadException is thrown when an application attempts to perform a networking operation on its main thread. This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged.

其他不可以在UI线程上做的事情比如有:

  1. 打开一个套接字(socket, eg: new Socket())
  2. 发送一个Http请求
  3. 连接一个远程的MySql数据库
  4. 下载文件

如果你想要在UI线程上做这些事情,请另起一个工作线程来执行。最简单的一个方式即使用Android所提供的AsyncTask,它可以让你在UI线程上做异步的操作。AsyncTask将会在一个工作线程上做耗时的操作,最后会返回结果给UI线程,这样子你就不需要自己去创建或者管理一个Thread。

所以最后,记住最重要的一点,不要直接在UI线程中做耗时的操作。

Android开发新手第一要素的更多相关文章

  1. Android开发新手常见的10个误区

    在过去十年中最流行的移动应用开发开发平台中,我们认为,Android平台是一个新开发的最方便的平台.一个廉价的工具,友好的开发者社区,众所周知的编程语言(Java),使得开发Android应用程序从未 ...

  2. Android开发新手学习总结(一)——使用Android Studio搭建Android集成开发环境

    [新手连载]一:使用Android Studio搭建Android集成开发环境http://bbs.itcast.cn/forum.php?mod=viewthread&tid=87055&a ...

  3. 【Android开发】 第一课 环境搭建教程

    Windows 开发环境部署: Android Studio 中文社区:http://www.android-studio.org/ 本教程将分为五个步骤来完成Android开发环境的部署. 第一步: ...

  4. Android开发新手问题

    因为最近在用空闲时间学习Android开发,期间确实遇到了一些问题.而且因为我之前在公司里一直都是在使用Eclipse进行开发,所以最初我学习Android时也就选择了Google的包含android ...

  5. Android开发的第一天

    不管做什么开发都是有开始的,对于开发的话开始要的准备的就是开发工具了  安装开发工具配置开发工具好了不多说了现在我来说怎么样安装和配置安卓的开发工具吧 第一首先就是要下载一个JDK (Java SE ...

  6. Android开发新手教程--Android应用程序结构

    一.新HelloWorld工程: 1.打开Eclipse.点击"File"->"New"->"Project"-Android ...

  7. Android开发-之第一个程序:HelloWorld!

    小编觉得不管学习什么编程的时候,第一个程序都是要求打印输出一个"HelloWorld!",那就从最简单的HelloWorld开始吧!哈哈~~~~ 一.创建一个Android工程 1 ...

  8. Android开发新手学习总结(六)——android开发目录结构【图文版】

    转载链接:http://bbs.itcast.cn/thread-87059-1-1.html?rss 既然已经搭建好环境了,那就对Android Studio中项目目录结构做个简单的了解了,这里以最 ...

  9. Android开发新手HelloWorld解析

    首先看这个 HelloWorld 类. Java代码public class HelloWorld extends Activity {       /** Called when the activ ...

随机推荐

  1. 《SQL Server企业级平台管理实践》读书笔记——几个系统库的备份与恢复

    master数据库 master作为数据库的主要数据库,记录着SQL Server系统的所有系统级信息,例如登录用户.系统配置设置.端点和凭证以及访问其他数据服务器所需要的信息.master数据库还记 ...

  2. 第三篇 :微信公众平台开发实战Java版之请求消息,响应消息以及事件消息类的封装

    微信服务器和第三方服务器之间究竟是通过什么方式进行对话的? 下面,我们先看下图: 其实我们可以简单的理解: (1)首先,用户向微信服务器发送消息: (2)微信服务器接收到用户的消息处理之后,通过开发者 ...

  3. 树莓派3 安装ubuntu-mate

    1.系统安装 1.1.下载ubuntu-mate镜像:https://ubuntu-mate.org/raspberry-pi/ 下载SDFormatterv4:https://www.sdcard. ...

  4. PHP水印类

    <?php /** * 水印类 * @author zhaoyingnan 2015/07/16 **/ include_once('extend.php'); class Watermark_ ...

  5. html跳转倒计时

    <html> <head> <title>出错啦~~~</title> <link href="css/login1.css" ...

  6. AMO olap Test C# generate tsql and mdx

    通过AMO访问online的cube,生成等值的TSql和mdx 自动生成等值的TSQL和MDX进行Cube测试.其中难度比较大的部分是拼接TSQL. 暂时不处理calculations,只除理met ...

  7. selenium操作滚动条的几种方式

    1.操作滚动条到当前可见视图的元素位置 WebElement element = dr.findElement(By.id("4")); ((JavascriptExecutor) ...

  8. 半径无关单核单线程最快速高斯模糊实现(附完整C代码)

    之前,俺也发过不少快速高斯模糊算法. 俺一般认为,只要处理一千六百万像素彩色图片,在2.2GHz的CPU上单核单线程超过1秒的算法,都是不快的. 之前发的几个算法,在俺2.2GHz的CPU上耗时都会超 ...

  9. python中str()和repr()的区别

    >>> s = 'Hello, world.' >>> str(s) 'Hello, world.' >>> repr(s) "'Hel ...

  10. HDU 4930 Fighting the Landlords --多Trick,较复杂模拟

    题意:两个人A和B在打牌,只有题目给出的几种牌能出若A第一次出牌B压不住或者A一次就把牌出完了,那么A赢,输出Yes,否则若A牌没出完而且被B压住了,那么A输,输出No. 解法:知道规则,看清题目,搞 ...