很多新手开发程序的时候,或者将原来跑在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. 返回顶部 和ico标题图片的制作

    <link rel="shortcut icon" href="bitbug_favicon.ico">---比特虫ico网页快速制作<tit ...

  2. Nde模块篇

    /*模块分为两种:原生模块和文件模块.原生模块即Node.js API提供的原生模块,原生模块在启动时已经被加载.文件模块即为动态加载模块,加载文件模块的工作主要由原生模块 module 来实现和完成 ...

  3. Java异常处理和设计【转】

    Java异常处理和设计 在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常 ...

  4. hibernate查询方式

    hibernate查询方式:1.本地SQL查询 2.HQL查询 3.QBC查询 HQL查询:是面向对象的查询语言,是使用最广的一种查询方法 QBC查询:Query by Criteria是一套接口来实 ...

  5. Sharepoint-Hosted App in 2013资料

    一个完整的流程,可参考网址 My First Sharepoint-Hosted App in 2013 部署第一个APP会遇到各种问题,可以参考网址 App development in Share ...

  6. mod_rewrite

    一.简介 http://www.07fly.net/a/wangluobiancheng/Phpbiancheng/201501/58393.html   二.实现原理:       只有当用户的WE ...

  7. hdu Flow Problem (最大流 裸题)

    最大流裸题,贴下模版 view code#include <iostream> #include <cstdio> #include <cstring> #incl ...

  8. GUID分区与MBR分区

    1.MBR分区表类型的磁盘主引导记录(Master Boot Record,缩写:MBR),又叫做主引导扇区,它仅仅包含一个64个字节的硬盘分区表.由于每个分区信息需要16个字节,所以对于采用MBR型 ...

  9. Hadoop 2.0中单点故障解决方案总结

    Hadoop 1.0内核主要由两个分支组成:MapReduce和HDFS,众所周知,这两个系统的设计缺陷是单点故障,即MR的JobTracker和HDFS的NameNode两个核心服务均存在单点问题, ...

  10. jQuery时间轴插件:jQuery Timelinr

    前言 这是一款可用于展示历史和计划的时间轴插件,尤其比较适合一些网站展示发展历程.大事件等场景.该插件基于jQuery,可以滑动切换.水平和垂直滚动.支持键盘方向键.经过扩展后可以支持鼠标滚轮事件. ...