Android开发 ---多线程操作:Handler对象,消息队列,异步任务下载

 

效果图:

  

 

 

 

 

1、activity_main.xml

  描述:定义了六个按钮

    

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:id="@+id/showNumber"android:textSize="35dp"android:gravity="center"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="0"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="开始计数"android:onClick="doStart"android:layout_weight="1"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="结束计数"android:onClick="doStop"android:layout_weight="1"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="开始计数2"android:onClick="doStart2"android:layout_weight="1"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="结束计数2"android:onClick="doStop2"android:layout_weight="1"/></LinearLayout><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="子线程和子线程之间的通信"android:onClick="test_1"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="异步任务"android:onClick="test_2"/>
</LinearLayout>

2、MainActivity.java

package com.nf.android_thread;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;public class MainActivity extends Activity {
  //用来显示数字
private TextView showNumber;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);showNumber = (TextView)findViewById(R.id.showNumber);//弹出提示Toast.makeText(this,"程序开始",Toast.LENGTH_SHORT).show();//将耗时操作放到子线程中,将不会阻塞主线程运行new Thread(new Runnable() {@Overridepublic void run() {try{
            //线程休眠20秒Thread.currentThread().sleep(
20000);}catch (InterruptedException e){e.printStackTrace();}}}).start();Toast.makeText(this,"程序结束",Toast.LENGTH_SHORT).show();}//声明一个主线程的Handler对象
  /*
    handler:
    消息的封装者和处理者,handler负责将需要传递的信息封装成Message,通过调用handler对象的obtainMessage()来实现;
    将消息传递给Looper,这是通过handler对象的sendMessage()来实现的。继而由Looper将Message放入MessageQueue中。
    当Looper对象看到MessageQueue中含有Message,就将其广播出去。
    该handler对象收到该消息后,调用相应的handler对象的handleMessage()方法对其进行处理。
  
  */
  /*
    Message:
    消息对象,Message Queue中的存放的对象。一个Message Queue中包含多个Message。
    Message实例对象的取得,通常使用Message类里的静态方法obtain(),该方法有多个重载版本可供选择;
    它的创建并不一定是直接创建一个新的实例,而是先从Message Pool(消息池)中看有没有可用的Message实例,存在则直接取出返回这个实例。
    如果Message Pool中没有可用的Message实例,则才用给定的参数创建一个Message对象。
    调用removeMessages()时,将Message从Message Queue中删除,同时放入到Message Pool中。
    除了上面这种方式,也可以通过Handler对象的obtainMessage()获取一个Message实例。
  */
  /*
    MessageQueue
    是一种数据结构,见名知义,就是一个消息队列,存放消息的地方。每一个线程最多只可以拥有一个MessageQueue数据结构。
    创建一个线程的时候,并不会自动创建其MessageQueue。通常使用一个Looper对象对该线程的MessageQueue进行管理。
    主线程创建时,会创建一个默认的Looper对象,而Looper对象的创建,将自动创建一个Message Queue。
    其他非主线程,不会自动创建Looper,要需要的时候,通过调用prepare函数来实现。
  */
  /*
    Looper:
    是MessageQueue的管理者。每一个MessageQueue都不能脱离Looper而存在,Looper对象的创建是通过prepare函数来实现的。
    同时每一个Looper对象和一个线程关联。通过调用Looper.myLooper()可以获得当前线程的Looper对象创建一个Looper对象时,会同时创建一个MessageQueue对象。
    除了主线程有默认的Looper,其他线程默认是没有MessageQueue对象的,所以,不能接受Message。
    如需要接受,自己定义一个Looper对象(通过prepare函数),这样该线程就有了自己的Looper对象和MessageQueue数据结构了。
    Looper从MessageQueue中取出Message然后,交由Handler的handleMessage进行处理。
    处理完成后,调用Message.recycle()将其放入Message Pool中。
  */private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg){super.handleMessage(msg);
       //判断来自哪个线程的handler
if (msg.what == 1){
          //给ui控件绑定计算得到的数字showNumber.setText(msg.arg1
+"");}}};//开始计数int number = 1;boolean isRun;public void doStart(View view){isRun = true;new Thread(new Runnable() {@Overridepublic void run() {while (isRun){//将计数发送给UI线程【Main Thread】
            // 这里的数据data我们必须发送给UI的主线程,所以我们通过Message的方式来做桥梁。Message message = Message.obtain();
            //设置handler版本message.what
= 1;message.arg1 = number;//如果将消息发给主线程呢
            //调用handler的sendMessage()方法,将得到的数字传进去 handler.sendMessage(message);SystemClock.sleep(1000);number++;}}}).start();}
   //当点击停止按钮时,将isRun设置为false,并将number设置为1
public void doStop(View view){isRun = false;number = 1;}

public void doStart2(View view){isRun = true;new Thread(new Runnable() {@Overridepublic void run() {while (isRun){//UI多线程中不能直接更新UIrunOnUiThread(new Runnable() {@Overridepublic void run() {showNumber.setText(number+"");}});number++;SystemClock.sleep(1000);}}}).start();}public void doStop2(View view){doStop(view);}public void test_1(View view){Intent intent = new Intent(this,Thread2Activity.class);startActivity(intent);}public void test_2(View view){Intent intent = new Intent(this,AsyncTaskActivity.class);startActivity(intent);} }

3、activity_thread2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/activity_thread2"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/showNumber"android:text="0"android:textSize="40dp"android:gravity="center"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="开始计算"android:onClick="doStart"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="停止计算"android:onClick="doStop"/>
</LinearLayout>

4、Thread2Activity.java

package com.nf.android_thread;import android.app.Activity;
import android.app.Notification;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.TextView;import java.util.Random;public class Thread2Activity extends Activity {private TextView showNumber;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_thread2);showNumber = (TextView)findViewById(R.id.showNumber);}
  
private Handler mainHandler = new Handler(){@Overridepublic void handleMessage(Message msg){super.handleMessage(msg);if (msg.what == 2){showNumber.setText(msg.arg1+"");}}};boolean isRun;int count = 0;Handler myHandler;public void doStart(View view){//用来处理数字平方的线程new Thread(new Runnable() {@Overridepublic void run() {
          //Android中的Looper类,是用来封装消息循环和消息队列的一个类,用于在android线程中进行消息处理。
          //handler其实可以看做是一个工具类,用来向消息队列中插入消息的。Looper.prepare();
//准备好一个消息队列myHandler = new Handler(){@Overridepublic void handleMessage(Message msg){super.handleMessage(msg);if (msg.what==1){Log.i("Thread2:","消息:"+msg.arg1);int number = msg.arg1*msg.arg1;Message message = Message.obtain();message.what = 2;message.arg1 = number;mainHandler.sendMessage(message);}}};Looper.loop();//循环 }}).start();
//开始计数的线程isRun = true;new Thread(new Runnable() {@Overridepublic void run() {while (isRun){int rand = new Random().nextInt(100);//获得随机数Log.i("Thread1:","随机数:"+rand);//发生消息到处理数字的线程Message msg = Message.obtain();msg.what = 1;msg.arg1 = rand;myHandler.sendMessage(msg);//通过Handler将消息发送到线程2count++;if (count>100)break;SystemClock.sleep(1000);}}}).start();}public void doStop(View view){isRun = false;count = 0;} }

5、activity_async_task.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/activity_async_task"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><ProgressBarandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/progressBar"style="@android:style/Widget.ProgressBar.Horizontal"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="开始下载"android:onClick="doStart"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="结束下载"android:onClick="doStop"/>
</LinearLayout>

6、AsyncTaskActivity.java

package com.nf.android_thread;import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;public class AsyncTaskActivity extends Activity {
  //进度条
private ProgressBar progressBar;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_async_task);progressBar =(ProgressBar)findViewById(R.id.progressBar);}MyAsyncTask task;//开启一个异步任务执行下载public void doStart(View view){
     //当点击开始按钮后,实例化一个异步任务task
= new MyAsyncTask();
      task.execute(
0);}//结束异步下载任务public void doStop(View view){task.cancel(true);}//构建一个异步任务class MyAsyncTask extends AsyncTask<Integer,Integer,String>{//必须的,执行异步操作
     //属于后台操作
     /**  
        * 这里的Integer参数对应AsyncTask中的第一个参数   
        * 这里的String返回值对应AsyncTask的第三个参数  
      * 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改  
      * 但是可以调用publishProgress方法触发onProgressUpdate对UI进行操作  
      */  
        @Overrideprotected String doInBackground(Integer...integers){for (int i=1;i<100;i++){publishProgress(i);//刷新进度SystemClock.sleep(100);}return "success";}//做一些初始化的操作
     //该方法运行在UI线程当中,并且运行在UI线程当中 可以对UI空间进行设置  @Override
protected void onPreExecute(){super.onPreExecute();Toast.makeText(AsyncTaskActivity.this,"开始下载",Toast.LENGTH_SHORT).show();}//得到后台操作返回的结果
    
/**  

       * 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值)  

        * 在doInBackground方法执行结束之后在运行,并且运行在UI线程当中 可以对UI空间进行设置  

       */ 

        @Overrideprotected void onPostExecute(String s){super.onPostExecute(s);if ("success".equals(s)){Toast.makeText(AsyncTaskActivity.this,"下载完毕",Toast.LENGTH_SHORT).show();}else{Toast.makeText(AsyncTaskActivity.this,"下载失败",Toast.LENGTH_SHORT).show();}}
     //更新进度
     

      /**  

         * 这里的Intege参数对应AsyncTask中的第二个参数  

         * 在doInBackground方法当中,每次调用publishProgress方法都会触发onProgressUpdate执行  

         * onProgressUpdate是在UI线程中执行,所以可以对UI空间进行操作  

         */  

        @Overrideprotected void onProgressUpdate(Integer... values){super.onProgressUpdate(values);//更新进度条progressBar.setProgress(values[0]);}}
}

 

转载于:https://www.cnblogs.com/zn615/p/8244844.html

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

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

相关文章

Lunx运维监控_shark巨菜_基础篇

Lunx运维监控_shark巨菜_基础篇一、监控重要性单单从“监控”两个字来谈&#xff0c;范围之广可以涵盖我们生活的方方面面&#xff0c;我们生活和工作中处处可见视频监控的摄像机&#xff1b;机房中的电压电流监控、干湿计、温度计&#xff1b;值班室的网络监控&#xff0c;网站…

java项目皮肤包_java swing项目皮肤包+使用方法说明

这是java swing项目皮肤包使用方法说明下载&#xff0c;项目可用的皮肤包&#xff0c;总共四个&#xff0c;自己下载总结的&#xff0c;包含使用代码说明。直接在main函数最开始加入说明代码即可使用~~~加入代码后记得处理异常&#xff01;软件介绍java swing项目皮肤包使用方法…

WinXP的EFS加密文件如何解密?

根据网上流传的资料&#xff0c;EFS&#xff08;Encrypting File System&#xff09;EFS加密是基于公钥策略的。在使用EFS加密一个文件或文件夹时&#xff0c;系统首先会生成一个由伪随机数组成的FEK(File Encryption Key&#xff0c;文件加密钥匙)&#xff0c;然后将利用FEK和…

关于滚动条出现页面跳动问题

二、CSS3计算calc和vw单位巧妙实现滚动条出现页面不跳动 很简单&#xff0c;只要一行代码就搞定了&#xff1a; .wrap-outer {margin-left: calc(100vw - 100%); } 或者&#xff1a; .wrap-outer {padding-left: calc(100vw - 100%); } 然后就可以庆祝放鞭炮啦&#xff01;&…

17款漂亮的 HTML5 网站模板免费下载

在过去的几年&#xff0c;设计师们已开始关注和使用 HTML5 了&#xff0c;如今 HTML5 得到了更加广泛的应用。今天&#xff0c;本文与大家分享17款免费的 HTML5 网站模板&#xff0c;看看有没自己喜欢的。 1- Smart Net 免费下载 2- Photo Art 免费下载 3- The Art Of Business…

java动态生成sdk_android、java制作sdk以及自动生成文档

最近一直在做android开发&#xff0c;昨天经理让我写个接口SDK做个接口文档&#xff0c;以便后面的开发。这让我很焦灼&#xff0c;SDK怎么做&#xff1f;要是只有敲代码还好。可是那个接口文档&#xff01;&#xff01;&#xff01;文档这东西最讨厌了&#xff0c;头都大了后来…

利用 Selenium 自动化 web 测试

Selenium 是一个健壮的工具集合&#xff0c;跨很多平台支持针对基于 web 的应用程序的测试自动化的敏捷开发。它是一个开源的、轻量级的自动化工具&#xff0c;很容易集成到各种项目中&#xff0c;支持多种编程语言&#xff0c;比如 .NET、Perl、Python、Ruby 和 Java™ 编程语…

乌班图 之 常用操作命令(二)

一、tree命令 tree [目录名]  以树状图列出文件目录 -d 只显示目录&#xff0c;不显示文件。 二、cp命令 cp即copy   cp 源文件 目标文件 -i  重名自动 覆盖 加了 -i 提示   y/n -r  复制目录及该目录下所有字目录和文件&#xff0c;目标文件必须是一个目录名。 三、…

Exchange2010外部传输域的使用方法

安装好EX2010后并不能马上与外部邮件进行收发&#xff0c;需要进行以下几个配置&#xff1a; 1、配置接收连接器 2、配置接受域 3、配置发送连接器 可以参考这个链接&#xff1a;http://www.chinaemail.com.cn/server/xtfl/Exchange/201101/59114.html 下面以我的实例来说明一…

Shiro安全框架入门篇

一、Shiro框架介绍 Apache Shiro是Java的一个安全框架&#xff0c;旨在简化身份验证和授权。Shiro在JavaSE和JavaEE项目中都可以使用。它主要用来处理身份认证&#xff0c;授权&#xff0c;企业会话管理和加密等。Shiro的具体功能点如下&#xff1a; &#xff08;1&#xff09;…

asp.net ajax1.0基础回顾(七):综合应用

本文将通过学生信息管理来介绍asp.net ajax的综合应用实例&#xff0c;包括“浏览”、“查询”、“添加”和“多选删除”功能&#xff0c;以及其它相关设计。 本示例源代码下载地址&#xff1a;http://down.51cto.com/data/220541 本示例中&#xff0c;程序架构参考Petshop&…

ASP.NET MVC3书店--第五节 表单编辑(第二部分)(转)

http://blog.sina.com.cn/s/blog_6ad539a90100r469.html5.5 使用HTML帮助器来截短文字 使用我们的StoreManager控制器中的Index方法添加视图的时候&#xff0c;有一个潜在的问题。事实上&#xff0c;我们的书名与作者名属性的长度值可能超出页面上 所定义的这两个列的长度。我们…

前端“黑话”polyfill

前言 在Web前端开发这个日新月异的时代&#xff0c;总是需要阅读一些最新的英文技术博客来跟上技术的发展的潮流。而有时候会遇到一些比较高频的“黑话”&#xff0c;在社区里面可能已经是人人皆知的“共同语言”&#xff0c;而你接触的少就偏偏看不懂。就像现在几乎所有中国人…

java 什么是线程同步,java多线程同步集合是什么?并发集合是什么?

java中关于集合的内容也是十分丰富的&#xff0c;而且相关的知识点也是十分多的。多线程集合所涵盖的范围是十分广阔的。今天就来为大家介绍一下&#xff0c;java多线程同步集合是什么以及并发集合是什么?一起来看看吧。首先我们需要知道的是&#xff0c;无论是同步集合还是并…

mysql数据库面试总结(一)

1、数据库优化  1&#xff09;数据库范式 第一范式&#xff08;1NF&#xff09;&#xff1a;强调的是列的原子性&#xff0c;即列不能够再分成其他几列。 如电话列可进行拆分---家庭电话、公司电话 第二范式&#xff08;2NF&#xff09;&#xff1a;首先是 1NF&#xff0c;另外…

思科路由器IKEV2 L2L***预共享密码认证最简化配置

一.概述:思科路由器对于IKEV2&#xff0c;是有很多预配的&#xff0c;因此可以很少的配置就能完成IKEV2的配置。二.基本思路&#xff1a;A.两边都用SVTI的方式配置Flex ***B.没有用动态路由&#xff0c;配置静态路由,如果一边用DVTI&#xff0c;则需要两边配置静态路由三.测试拓…

关于通过Sql注入直接拖数据的讨论

和谐社会&#xff0c;拒绝***。 最近在老外的Blog上逛&#xff0c;突然发现我一直以来Dump数据的态度终于得到了某些老外的认可&#xff0c;通过Sql注入点直接拖下数据库是可行的。而且很多老外已经开始开发这方面的直接Dump数据的工具&#xff0c;并讨论相关的算法。很多人说行…

UVA10561 Treblecross

Treblecross 题目大意&#xff1a;给定一个带有.和X的字符串作为初始局面&#xff0c;两人轮流游戏&#xff0c;将.修改为X&#xff0c;当一个人放下X后&#xff0c;出现三个连续的X&#xff0c;游戏接触&#xff0c;放下X的人获胜。判断先手必胜还是必败&#xff0c;并给出第一…

解决VS2005 远程工具无法通过同步软件连接S5pv210 样机的问题

居然无法连接&#xff0c;记得以前遇到过的 1 分钟前 上传下载附件 (58.21 KB)后来还是看MSDN解决了MSDN连接如下http://msdn.microsoft.com/en-us/library/ee480836.aspx——Troubleshooting a Connection to a Target Device That Uses Platform Manager 转载一下sunrain_hjb…

一些应该记住的东西(持续更新?再也不会更新了)

没什么用的目录 1.积性函数与杜教筛 2.搜索的几种优化与考试期望得分 3.乱讲 4.模拟退火系列 5.生成函数系列 2018.1.18 首先写写数学方面的吧(因为现在在学)……毕竟这里面的公式浩如烟海…… 对着表推了十分钟愣是没发现……明明上午还证明过…… 还有就是通过算贡献化简一些…