android分开两个线程做事,android开发教程之handle实现多线程和异步处理

这次浅谈一下Handler,为什么会出现Handler这个功能特性呢?首先,在之前的基本控件,基本都是在Activity的onCreate(Bundle savedInstanceState)方法中调用和处理的,但是,在有些情况,比如在网络上下载软件等一些需要等待响应时间比较长的操作,如果同样放在Activity的该方法中的话,那么在执行该方法的时候,整个Activity是不可动的,用户只能干等着,这样的用户体验是十分差的,这种处理方式带来的最好结果是等待了一段时间后,得到了想要的结果,不好的情况就是等了N久,也没有出现结果,有的甚至会使Activity报错,为了避免这些情况的发生,所以引入了Handler的特性,他就像是一个线程队列,它也是一种异步的消息处理。

首先我们先看一个例子,通过例子来对Handler进行认识。

布局文件中是两个按钮,分别是start和stop,分别控制线程的开始和停止。

代码如下:

在Activity中的代码如下:

代码如下:

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

public class HandlerDemo1Activity extends Activity {

Button startButton = null;

Button endButton = null;

Handler handler = new Handler();

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

startButton = (Button)findViewById(R.id.start);

startButton.setOnClickListener(new StartListener());

endButton = (Button)findViewById(R.id.end);

endButton.setOnClickListener(new EndListener());

}

class StartListener implements OnClickListener{

@Override

public void onClick(View arg0) {

// TODO Auto-generated method stub

handler.post(HandlerThread);

}

}

class EndListener implements OnClickListener{

@Override

public void onClick(View arg0) {

// TODO Auto-generated method stub

handler.removeCallbacks(HandlerThread);

}

}

Runnable HandlerThread = new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

System.out.println("HandlerThread is Running......");

handler.postDelayed(HandlerThread, 3000);

}

};

}

我们可以看到,在Activity中对两个按钮分别绑定了事件监听器,还创建了Handler的一个实例,以及创建了一个匿名内部类,是一个实现Runnable接口的线程HandlerThread。

当start按钮按下时,即会执行handler.post(HandlerThread);这一句代码,之前说过,Handler用一个线程队列,这句代码即是把HandlerThread这个线程加入了handler的线程队列中,因为加入的这个HandlerThread是第一个线程,因此它会马上执行它的run()方法。在run()方法中,handler.postDelayed(HandlerThread, 3000);又再一次将HandlerThread放入handler的线程队列中,这里设置了3000ms的延迟。这样,整个程序会不断地运行,且每隔3000ms在LogCat中打印出"HandlerThread is Running......"。

但是,值得注意的是,不要以为现在handler的出现,使得这些打印操作所在的线程和主线程分开了,其实不然,这里根本没有两个线程在跑,这些打印出来的内容,也是主线程跑出来的。我们可以做个试验,在onCreate函数之后以及打印语句的地方把当前的Thread的名字通过Thread.currentThread.getName()打印出来,可以看到,都是相同的,都是main,这就意味着都是主线程跑出来的。我们知道一个线程的启动需要start()方法,而在这个程序中并没有对HandlerThread进行start,而是直接调用了run()方法了。所以只是main线程在跑就不足为奇了。

从上面的例子来看,这个Handler如果这样用的话,并不是我们想要的效果,因为它没有实现异步,还是在一个主线程中运行。

因此,我们必须换一种方式来使用Handler。

要实现Handler的异步多线程,就需要了解另两个类,一个是Message类,另一个是Looper类。

每个Handler对象中都有一个消息队列,队列中就是存放的Message对象,可以使用obtainMessage()来获得消息对象。同时,Message对象是用来传递使用的,它能传递两个整型和一个Object,尽量使用Message的arg1与arg2两个整型来传递参数,那样系统消耗最小(API如是说),如果传递数据量比较大,则可以使用setData(Bundle a)的方法,其中的Bundle对象可以粗略的看成是一个Map对象,但它的Key都是String,而value是有限的一些类型,可以再API里查看。

Looper类有能够循环地从消息队列中取得消息的功能,我们可以在一个线程中使用Looper,这样,该线程就可以循环的在消息队列里取得消息,知道消息队列为空为止。但我们一般不直接创建和使用Looper,在Android提供的HandlerThread类中,就实现了Looper的功能,所以我们只要使用HandlerThread这个类就可以了,我们用HandlerThread的对象调用getLooper()来得到该线程的Looper对象。

我们来看下面这个例子

代码如下:

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.HandlerThread;

import android.os.Looper;

import android.os.Message;

public class HandlerDemo2Activity extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

System.out.println("Activity---->"+Thread.currentThread().getName());

HandlerThread handlerThread = new HandlerThread("HandlerThread");//创建一个HandlerThread对象,它是一个线程

handlerThread.start();//启动线程

MyHandler myHandler = new MyHandler(handlerThread.getLooper());//创建一个MyHandler对象,该对象继承了Handler,从下面的MyHandler类中可以看到,调用的是Handler父类的Handler(Looper looper)的构造函数,而这里传进去的Looper对象是从HandlerThread中取得的。

Message msg = myHandler.obtainMessage();//获得消息对象

msg.sendToTarget();//把得到的消息对象发送给生成该消息的Handler,即myHandler,当myHandler接收到消息后,就会调用其handleMessage的方法来处理消息

}

class MyHandler extends Handler{

public MyHandler() {//构造函数

// TODO Auto-generated constructor stub

}

public MyHandler(Looper looper){//构造函数

super(looper);//实现了父类的该构造函数

}

@Override

public void handleMessage(Message msg) {//当这个Handler接收到Message对象的时候,会自动调用这个方法,来对Message对象进行处理

// TODO Auto-generated method stub

System.out.println("Handler---->"+Thread.currentThread().getName());

}

}

}

上面的代码在LogCat中System.out的执行结果为:

Acitivity---->main

Handler---->HandlerThread

这就说明了,使用Handler,结合Looper和Message,可以实现与主线程的分离,从而可以实现多线程和异步处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/541265.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

夏夜

儿时的夏夜毕竟是最有夏夜的味道。屋堂的煤油灯啪嗒的跳动,忽明忽暗,真怕它脆弱的明亮突然变黑暗。屋外弯月星稀,月光优雅的撒在平静的湖面上,清纯而又温和。水鸟在湖岸边慵懒的伸了伸脖子。正享受着夏夜的宁静和清凉。调皮的小孩…

Python operator.lt()函数与示例

operator.lt()函数 (operator.lt() Function) operator.lt() function is a library function of operator module, it is used to perform "less than operation" on two values and returns True if the first value is less than the second value, False, otherw…

android实现滑动切换图,Android:使用ViewPager实现左右滑动切换图片加点点

图片发自简书App1、引入android-support-v4.jar包&#xff0c;在主布局里加入< ?xml version"1.0" encoding"utf-8"?>< RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.…

div的替代品

人们在标签使用中最常见到的错误之一就是随意将HTML5的<section>等价于<div>——具体地说&#xff0c;就是直接用作替代品(用于样式)。在XHTML或者HTML4中&#xff0c;我们常看到这样的代码&#xff1a; <!-- HTML 4-style code --> <div id"wrapper…

threadgroup_Java ThreadGroup list()方法与示例

threadgroupThreadGroup类的list()方法 (ThreadGroup Class list() method) list() method is available in java.lang package. list()方法在java.lang包中可用。 list() method is used to list or display information (like name, priority, thread group, etc.) to the st…

html的柱状图去除右边纵坐标,excel如何把次坐标轴逆序

excel2010设置水平坐标轴逆序类型,但垂直坐标轴刻设置水平坐标轴逆序且垂直坐标轴轴仍位于图表左侧的步骤是&#xff1a;打开带有图表的Excel工作表&#xff1b;在图表区域的水平轴标签位置双击鼠标左键&#xff0c;打开“设置坐标轴格式”&#xff1b;勾寻逆序类别”&#xff…

jhipster项目迁移websocket

2019独角兽企业重金招聘Python工程师标准>>> 1、 在项目目录下命令行安装 两个组件 bower install sockjs-client bower install stomp-websocket 2、在index.html 中加入组件js的引用 <script src"bower_components/sockjs-client/dist/sockjs.js">…

Java包hashCode()方法及示例

包类hashCode()方法 (Package Class hashCode() method) hashCode() method is available in java.lang package. hashCode()方法在java.lang包中可用。 hashCode() method is used to return the hashcode of the package calculated from the package name. hashCode()方法用…

html 图片上放置按钮,用CSS在图片上再加一个小按钮

很简单的&#xff0c;嗯&#xff0c;就是要做成这样的&#xff1a;用CSS&#xff0c;当然得用层了&#xff0c;就是在图片上再加一个层&#xff0c;用来放那个按钮&#xff0c;按钮又有两种方式可以放&#xff0c;一种是直接用图片img标签&#xff0c;一种是通过背景图片放上去…

html点击导航变色,点击导航后,当前导航的颜色变色

html>Documentnav ul {padding: 0;list-style: none;}nav ul li {text-decoration: none;width: 70px;line-height: 50px;text-align: center;float: left;background-color: #000;color: #fff;cursor: pointer;}.gray {background-color: rgba(0,0,0,0.6);}首页实战路径猿问…

Java扫描仪toString()方法及示例

扫描仪类toString()方法 (Scanner Class toString() method) toString() method is available in java.util package. toString()方法在java.util包中可用。 toString() method is used to string denotation of this Scanner and it contains information related to tracing.…

怎么将oracle的sql文件转换成mysql的sql文件

怎么将sql文件导入PowerDesigner中的方法(将oracle的sql文件转换成mysql的sql文件)呢&#xff1f; 怎么将xx.sql文件的数据库结构导入powerdesigner 的方法呢? 现讲下。 工具/原料 PowerDesigner软件&#xff0c;oracle数据库 方法/步骤 将要导入的库的所有表的表结构(不要表数…

ios html图片相对路径,iOS 下加载本地HTML/js/css/image 等路径问题

今天在项目中遇到一个问题&#xff1a;我将H5的文件拖入项目中&#xff0c;在webView上添加H5,运行时发现H5的样式与图片等都没屏幕快照 2016-07-06 11.33.22.png有了。经过多种测试后发现&#xff1a;是路径的问题。在ios项目下添加本地HTML/js/css/image 当拖入项目时有两种选…

nextfloat_Java Random nextFloat()方法与示例

nextfloat随机类nextFloat()方法 (Random Class nextFloat() method) nextFloat() method is available in java.util package. nextFloat()方法在java.util包中可用。 nextFloat() method is used to generate the next pseudo-random float value between the range 0.0 and …

mac自己定义tree命令

编辑文件: vim ~/.bash_profile 在文件末尾追加: alias tree"find . -print | sed -e s;[^/]*/;|____;g;s;____|; |;g" 应用配置: source ~/.bash_profile 转载于:https://www.cnblogs.com/gavanwanggw/p/6962533.html

Java Hashtable keySet()方法与示例

哈希表类keySet()方法 (Hashtable Class keySet() method) keySet() method is available in java.util package. keySet()方法在java.util包中可用。 keySet() method is used to return a set of keys to be viewed in a set in this Hashtable. keySet()方法用于返回要在此H…

el-calendar 怎么设置上一年和下一年_为什么香港硕士一年的含金量那么高?

为什么香港硕士研究生只读一年但含金量更高&#xff1f;近些年来香港留学大热&#xff0c;其中一个原因就是香港的授课式硕士研究生仅需一年就可以拿到学位。对于学生来说&#xff0c;在享受到国际一流的教学资源和工作机会的同时&#xff0c;既节省时间又节约金钱&#xff0c;…

武汉市江岸区2021年高考成绩查询,2021年武汉各区一、二、三批次高中有哪些(名单)...

5月5日至9日是武汉市中考网上报名填报志愿的日子&#xff0c;填报志愿之前应提前了解本区的一批次、二批次和三批次学校的名单&#xff0c;了解其历年录取分数线&#xff0c;并选中最合适最理想的一所学校进行填写&#xff0c;下面我们来看详细名单。武汉各区一、二、三批次高中…

《Java设计模式》之桥接模式

Bridge模式的概念 Bridge 模式是构造型的设计模式之中的一个。Bridge模式基于类的最小设计原则&#xff0c;通过使用封装&#xff0c;聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象&#xff08;abstraction&#xff09;与行为实现&#xff08;implement…

Java Formatter locale()方法与示例

Formatter类的locale()方法 (Formatter Class locale() method) locale() method is available in java.util package. locale()方法在java.util包中可用。 locale() method is used to returns the locales assign by the construction of this Formatter. locale()方法用于返…