android之Handler机制
简单例子开头: 网络http请求网站源码数据并显示
注意点:访问网络需要加Internet权限:
android.permission.INTERNET
简单的步骤:
使用UrlConnection请求一个url地址获取内容:
//1.创建一个Url对象
URL url = new URL(url_str);
//2.获取一个UrlConnection对象
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
//3.为UrlConnection对象设置一些请求的参数,请求方式,连接的超时时间
connection.setRequestMethod("GET");//设置请求方式
connection.setConnectTimeout(1000*10);//设置超时时间
//4.在获取url请求的数据前需要判断响应码,200 :成功,206:访问部分数据成功 300:跳转或重定向 400:错误 500:服务器异常
int code = connection.getResponseCode();
if(code == 200){
//5.获取有效数据,并将获取的流数据解析成String
InputStream inputStream = connection.getInputStream();
String result = StreamUtils.streamToString(inputStream);
}
注意:
(1)主线程不能够做耗时的操作,网络请求就是耗时的操作需要放到子线程做。
(2)子线程不能更新控件的内容(更新Ui)。所以产生了矛盾,解决办法就是使用Handler(处理消息机制).
(3)子线程一定不能更新UI?是错的, SurfaceView :多媒体视频播放 ,可以在子线程中更新UI;Progress(进度)相关的控件:也是可以在子线程中更新Ui;
审计机制:activity完全显示的时候审计机制才会去检测子线程有没有更新Ui. 当activity没有完全显示的时候子线程可以更新UI
******消息机制原理*****
Handler、Looper、MessageQuene之间的关系。
每一个线程最多有一个Looper、一个Looper里边含有一个MessageQuene。
Handler每次将消息发送到MessageQuene中,Looper用过一个死循环不断的从MessageQuene中获取消息,获取后,根据Message的target分发给对应的Handler进行处理。
Handler:消息机制的写法(重要)
使用Handler的步骤:
1.主线程中创建一个Handler
- private Handler handler = new Handler(){
//重写handler的handlermessage方法- public void handleMessage(android.os.Message msg) {
- };
- };
2.重写handler的handlermessage方法
3.子线程中创建一个Message对象,将获取的数据绑定给msg
- Message msg = new Message();
- //另一种方式:Message msg = Messge.obtain;
- msg.obj = result;
4.handler对象在子线程中将message发送给主线程
- handler.sendMessage(msg);
5. 主线程中handlermessage重写的方法中 接受子线程发来的数据,就可以做更新UI的操作。
- String result= (String) msg.obj;
下面是一个例子:
布局文件
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context="com.example.yb.myapplication.HttpUrlActivity">
- <EditText
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:id="@+id/ed_url"/>
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/bt_httpRequest"
- android:text="请求网页数据"/>
- <ScrollView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/tv_httpResponse"/>
- </ScrollView>
- </LinearLayout>
在Activity里面
- public class HttpUrlActivity extends AppCompatActivity implements View.OnClickListener {
- private Context mcontext;
- private TextView tv_httpResponse1;
- private EditText ed_url;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_http_url);
- mcontext=this;
- Button bt_httpRequest = (Button)findViewById(R.id.bt_httpRequest);
- ed_url = (EditText) findViewById(R.id.ed_url);
- tv_httpResponse1 = (TextView) findViewById(R.id.tv_httpResponse);
- bt_httpRequest.setOnClickListener(this);
- }
- //H.1在主线程中创建一个handler对象 ,这里是匿名内部类
- Handler handler=new Handler(){
- //H.2重新handleMessage方法
- @Override
- public void handleMessage(Message msg) {
- //H.5 接受子线程发来的 数据,处理数据
- String result= (String) msg.obj;
- //H.6当前线程是主线程,可以做UI的更新
- //5显示到TextView
- tv_httpResponse1.setText(result);
- }
- };
- @Override
- public void onClick(View v) {
- final String url_str = ed_url.getText().toString().trim();
- if (TextUtils.isEmpty(url_str)) {
- Toast.makeText(mcontext, "url不能为空", Toast.LENGTH_SHORT).show();
- return;
- }
- //匿名内部类可以用于接口上,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现。
- // 最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口。
- //创建一个子线程做网络请求
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- //四.请求url地址
- //1创建一个url对象
- URL url = new URL(url_str);
- //2获取一个urlConnection对象
- HttpURLConnection con = (HttpURLConnection) url.openConnection();
- //3设置urlConnection的参数:请求时间,请求方式
- con.setRequestMethod("GET");
- con.setConnectTimeout( * ); //超时时间
- //4根据请求的结果的响应码来判断,200成功,206部分数据访问成功。400错误,500服务器异常
- int code = con.getResponseCode();
- if (code == ) {
- //获取数据,并返回的流数据解析为String
- InputStream inputStream = con.getInputStream();
- //将获取的读取流解析为String字符串
- String result=StreamUtil.stremToString(inputStream);
- //H.3 子线程创建一个Message对象,为了携带子线程获取的数据给主线程
- Message msg=new Message();
- msg.obj=result;
- //H.4使用handler对象将消息发送给主线程
- handler.sendMessage(msg);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- }
- }
创建一个工具类StreamUtil ,里面写入把读取流转为String返回
- public class StreamUtil {
- /**
- * 获取的读取流转为String返回
- *
- * @param inputStream
- */
- public static String stremToString(InputStream in) {
- String result="";
- try {
- //创建一个字节数组写入流
- ByteArrayOutputStream out=new ByteArrayOutputStream();
- byte[] buffer=new byte[];
- int length=;
- while((length=in.read(buffer))!=-){ //如果返回-1 则表示数据读取完成了。
- out.write(buffer,,length);//写入数据
- out.flush();
- }
- result=out.toString();//写入流转为字符串
- out.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return result;
- }
- }
其他的消息处理:
使用handler直接post到主线程,handler需要在主线程创建
- //延迟多少毫米执行runnable。
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- tv_simple.setText("我被更新了");
- }
- }, *);
应用场景:广告展示后,做页面跳转。
android之Handler机制的更多相关文章
- Android的Handler机制
Handler机制的原理 Android 的 Handler 机制(也有人叫消息机制)目的是为了跨线程通信,也就是多线程通信.之所以需 要跨线程通信是因为在 Android 中主线程通常只负责 UI ...
- 10分钟了解Android的Handler机制
Handler机制是Android中相当经典的异步消息机制,在Android发展的历史长河中扮演着很重要的角色,无论是我们直接面对的应用层还是FrameWork层,使用的场景还是相当的多.分析源码一探 ...
- android之handler机制深入解析
一.android中需要另开线程处理耗时.网络的任务,但是有必须要在UI线程中修改组件.这样做是为了: ①只能在UI线程中修改组件,避免了多线程造成组件显示混乱 ②不使用加锁策略是为了提高性能,因为a ...
- 【转载】Android 的 Handler 机制实现原理分析
handler在安卓开发中是必须掌握的技术,但是很多人都是停留在使用阶段.使用起来很简单,就两个步骤,在主线程重写handler的handleMessage( )方法,在工作线程发送消息.但是,有没有 ...
- [转]Android中handler机制的原理
Andriod提供了Handler 和 Looper 来满足线程间的通信.Handler先进先出原则.Looper类用来管理特定线程内对象之间的消息交换(MessageExchange). 1)Loo ...
- 涛涛的小马甲 Android之Handler机制
首先需要了解一个基本的概念ANR:Application not response 即应用程序无响应,也就是俗话说的死机. 出现Anr的原因是: 主线程需要做很多重要的事情,响应点击事件,更新UI如果 ...
- Android Handler机制剖析
android的handler机制是android的线程通信的核心机制 Android UI是线程不安全的,如果在子线程中尝试进行UI操作,程序就有可能会崩溃. Android中的实现了 接收消息的& ...
- Android多线程通信机制
掌握Android的多线程通信机制,我们首先应该掌握Android中进程与线程是什么. 1. 进程 在Android中,一个应用程序就是一个独立的进程(应用运行在一个独立的环境中,可以避免其他应用程序 ...
- android的消息处理机制——Looper,Handler,Message
在开始讨论android的消息处理机制前,先来谈谈一些基本相关的术语. 通信的同步(Synchronous):指向客户端发送请求后,必须要在服务端有回应后客户端才继续发送其它的请求,所以这时所有请求将 ...
随机推荐
- Android-RelativeLayout(相对布局)
1.RelativeLayout(相对布局) 2.margin针对的是容器中的组件,而padding针对的是组件中的元素
- C语言 遍历流程 变量生命周期
来自c程序设计 谭浩强 程序编译流程 运行c程序的步骤 在编好一个c程序后.怎样上机进行编译运行呢?一般要经过一下几个步骤: 上机输入和编辑源程序.通过键盘和计算机输入程序,如果发现有错误,要及时改正 ...
- JS中获得当前时间的年月
//获取完整的日期 var date=new Date; var year=date.getFullYear(); var month=date.getMonth()+1; month =(month ...
- C#重启IIS指定网站和指定应用程序池
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- Python 爬取网站资源文件
爬虫原理: 以下来自知乎解释 首先你要明白爬虫怎样工作.想象你是一只蜘蛛,现在你被放到了互联“网”上.那么,你需要把所有的网页都看一遍.怎么办呢?没问题呀,你就随便从某个地方开始,比如说人民日报的首页 ...
- RAC+asm通过rman恢复到单实例+asm
1.恢复参数文件,并修改参数文件 参数文件指名几个最简单的就行,我的参数文件如下: 2.恢复控制文件,并启动数据库到mount 如果是把备份集从别的服务器拷贝到本地恢复的服务器的目录,使用下面的语句指 ...
- xamarin(3.9.236)里DATETIMENOW的错误。
[ERROR] FATAL UNHANDLED EXCEPTION: System.EntryPointNotFoundException: monodroid_get_system_property ...
- linux shell基础命令
du -h #查询磁盘文件大小和列表 df -h # 查询服务器磁盘使用情况 top/free # 查询服务器内存,cpu等资源使用情况 iptables # 防火墙相关的命令 vi ...
- Quartz定时调度框架
Quartz定时调度框架CronTrigger时间配置格式说明 CronTrigger时间格式配置说明 CronTrigger配置格式: 格式: [秒] [分] [小时] [日] [月] [周] [年 ...
- tecplot 脚本文件
一个简单的C++代码,可以生成tecplot的脚本文件,打开文件就能自动绘图.绘图过程是先把文件导入,然后镜像,最后生成一个动画,但是导入的文件名称要求是有规律的. /* ** This progra ...