Android学习历程2
来源:互联网 发布:注册域名是什么意思 编辑:程序博客网 时间:2024/05/16 19:36
上一篇的补充
在写了上一篇博客之后,突然想到对于一个初学者而言,有很多基础性的概念都不是很清楚,可能会让很多人迷惑,为什么要使用Asynctask,至少我自己当时见到的时候就很迷茫,因此在这里做一个补充。
Asynctask是安卓开发过程中所经常用到的两种异步加载的方式之一。可是在开发过程中,我们为什么要使用异步加载的方式呢?
异步加载的原因:
在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。在单线程模型中始终要记住两条法则:
1. 不要阻塞UI线程 (这里又会衍生出一个概念UI线程,什么是UI线程。顾名思义,ui线程就是管理着用户界面的那个线程!)
2. 确保只在ui线程中访问ui组件
当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。
比如说从网上获取一个网页,在一个TextView中将其源代码显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得页面源码后,是不能直接在网络操作线程中调用TextView.setText()的.因为其他线程中是不能直接访问主UI线程成员 。
为了解决这种情况,android为我们提供了很多办法。
1)、handler和message机制:通过显示的抛出、捕获消息与ui进行交互;
2)、Activity.runOnUiThread(Runnable):如果当前线程为ui线程,则立即执行;否则,将参数中的线程操作放入到ui线程的事件队列中,等待执行。
3)、View.post(Runnable):将操作放入到message队列中,如果放入成功,该操作将会在ui线程中执行,并返回true,否则返回false
4)、View.postDelayed(Runnable, long)跟第三条基本一样,只不过添加了一个延迟时间。
5)、android1.5以后为我们提供了一个工具类来搞定这个问题AsyncTask.
现在基本常用的就是第一和第五种,
介绍最本质的多线程:hanlder和message机制:
为何需要多线程:
在日常应用中,我们通常需要处理一些“后台,用户不可见”的操作,例如说,我们需要下载一个音乐,要是你的应用必须等用户下载完成之后才可以进行别的操 作,那肯定让用户非常的不爽。这时候,我们通常的做法是,让这些操作去后台执行,然后等后台执行完毕之后,再给用户弹出相应的提示信息。这时候,我们就需 要使用多线程机制,然后通过创建一个新的线程来执行这些操作。
明白了,实现需求,我们就准备着手实现了。但是,经过进一步的了解,我们悲剧的发现,android中的线程机制是,只能在UI线程中和用户进行交互。当 我们创建了一个新线程,执行了一些后台操作,执行完成之后,我们想要给用户弹出对话框以确认,但是却悲剧的发现,我们根本无法返回UI主线程了。
(说明:何为UI线程:UI线程就是你当前看到的这些交互界面所属的线程)。
这时候,我们如果想要实现这些功能,我们就需要一个android为我们提供的handler和message机制。
先讲解下编程机制:
我们通常在UI线程中创建一个handler,handler相当于一个处理器,它主要负责处理和绑定到该handler的线程中的message。每一 个handler都必须关联一个looper,并且两者是一一对应的,注意,这点很重要哦!此外,looper负责从其内部的messageQueue中 拿出一个个的message给handler进行处理。因为我们这里handler是在UI线程中实现的,所以经过这么一个handler、 message机制,我们就可以回到UI线程中了。
何为handler:处理后台进程返回数据的工作人员。
何为message:后台进程返回的数据,里面可以存储bundle等数据格式
何为messageQueue:是线程对应looper的一部分,负责存储从后台进程中抛回的和当前handler绑定的message,是一个队列。
何为looper:looper相当于一个messageQueue的管理人员,它会不停的循环的遍历队列,然后将符合条件的message一个个的拿出来交给handler进行处理。
注意,handler是在UI线程中声明的,如果我们直接用类似代码执行一个线程的话,实际上并没有创建一个新的线程,因为handler已经跟默认的UI线程中的looper绑定了。
如果有兴趣的话,可以去看下Handler的默认空构造函数便知道原因了,里面直接绑定了当前UI线程的looper。
handler介绍
既然前面说到了Asnctask和hadler是安卓开发过程中常用的两种异步加载的方式,前一章也简单介绍了Asnctask的用法,现在在这里简单介绍一下handler的使用
Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分逐个的在消息队列中将消息取出,然后对消息进行出来,就是发送消息和接收消息不是同步的处理。 这种机制通常用来处理相对耗时比较长的操作。
通常情况下,当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进行事件分发。如果此时需要一个耗时的操作,例如:联网读取数据,或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,如果你放在主线程中的话,界面会出现假死现象,如果5秒钟还没有完成的话,会收到Android系统的一个错误提示”强制关闭”。
这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,但是当子线程中有涉及到操作UI的操作时,就会对主线程产生危险,也就是说,更新UI只能在主线程中更新,在子线程中操作是危险的. 这个时候,Handler就出现了来解决这个复杂的问题,由于Handler运行在主线程中(UI线程中),它与子线程可以通过Message对象来传递数据,这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传递)Message对象,(里面包含数据), 把这些消息放入主线程队列中,配合主线程进行更新UI。
Handler工具类在多线程中有两方面的应用:
1、发送消息,在不同的线程间发送消息,使用的方法为sendXXX();。
android.os.Handler对象通过下面的方法发送消息的:
sendEmptyMessage(int),发送一个空的消息;
sendMessage(Message),发送消息,消息中可以携带参数;
sendMessageAtTime(Message, long),未来某一时间点发送消息;
sendMessageDelayed(Message, long),延时Nms发送消息。
2、计划任务,在未来执行某任务,使用的方法为postXXX();。
android.os.Handler对象通过下面的方法执行计划任务:
post(Runnable),提交计划任务马上执行;
postAtTime(Runnable, long),提交计划任务在未来的时间点执行;
postDelayed(Runnable, long),提交计划任务延时Nms执行。
在使用handler的时候,首先要声明一个handler对象,并重写以下方法,
private Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case TryCatch:
HideLoading();
Toast.makeText(mContext, “错误号码101”, Toast.LENGTH_SHORT).show();
break;
default:
break;
}
super.handleMessage(msg);
}
};
在声明了对象之后,在需要执行异步加载的地方,写下如下代码:
mHandler.sendEmptyMessage(TryCatch1);
- Android学习历程2
- android学习历程2--搭建开发环境
- android学习历程1
- Android学习历程
- Android学习历程
- android学习历程
- Android学习历程
- Android学习历程1
- Android学习历程---Android布局
- 一个android的学习历程
- android学习历程3--HelloWorld
- android学习历程4--activity
- android 学习历程之--蓝牙
- android截屏学习历程
- Android学习历程之【安装】
- Junit学习历程(2)
- Junit学习历程(2)
- Junit学习历程(2)
- 彻底理解ThreadLocal
- 调用opencv库进行身份证号码识别主要流程
- git原理及使用
- C++封装、继承、多态
- Eclipse->Run On Server 错误:Project facet Java version 1.7 is not supported.
- Android学习历程2
- SQL 执行错误 # 1005 从数据库的响应
- 常用Xcode插件推荐(持续更新)
- Windows实现基于TCP的网络应用程序
- linux服务器添加硬盘
- NSArray&NSMutableArray常用操作梳理
- DataNode引用计数磁盘选择策略
- ASP.NET发布WebService(原)
- framework(一):ActivityThread-笔记