文档章节

android中Handler的初步认识(三)

tiansl
 tiansl
发布于 2015/01/21 15:42
字数 928
阅读 14
收藏 0

  在上一个例子中,最终我们发现,其实用到的线程只有一个,那就是程序的主线程(UI线程)。那么怎么把那个例子改成用新建的线程来实现呢,今天我尝试了一下,写了下面这个小程序。

        当然,首先要声明一下,今天的这个例子并不是推荐的写法,而是我为了学习多线程而写的例子(貌似更常用的是AsyncTask,而不是Thread和Handler去更新UI)。


        在今天的这个例子中,我用到了Looper,先说说Looper是什么


在API中是这么解释Lopper的:Class used to run a message loop for a thread。我的理解是Looper是用来控制message queue的类


Looper常用的几个用法有:

Looper.prepare()                安卓的主线程中会默认调用这个方法来创建消息队列。但是,如果我们自己新建的线程,如果需要消息队列,则需要手动调用这个方法。

Looper.loop()                     这个方法用在prepare()方法之后,调用该方法之后,进入消息循环。

Looper.getMainLooper()  我在代码中用到了这个方法,这个方法的作用是获得主线程的Looper实例

Looper.myLooper()            这个方法用到获取当前线程的Looper实例


今天这个例子和第二篇中实现的功能一下,我只不过改了一个写法而已,下面是代码:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片

  1. package com.example.handler2;  

  2.   

  3. import android.app.Activity;  

  4. import android.os.Bundle;  

  5. import android.os.Handler;  

  6. import android.os.Looper;  

  7. import android.os.Message;  

  8. import android.util.Log;  

  9. import android.view.View;  

  10. import android.view.View.OnClickListener;  

  11. import android.widget.Button;  

  12. import android.widget.ProgressBar;  

  13.   

  14. public class MainActivity extends Activity {  

  15.   

  16.     Button startButton = null;  

  17.     Button stopButton = null;  

  18.     ProgressBar progressbar = null;  

  19.     Thread counter = null;  

  20.   

  21.     //获取主线程的looper  

  22.     Looper looper = Looper.getMainLooper();  

  23.   

  24.       

  25.     @Override  

  26.     protected void onCreate(Bundle savedInstanceState) {  

  27.         super.onCreate(savedInstanceState);  

  28.         setContentView(R.layout.activity_main);  

  29.           

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

  31.         stopButton = (Button) findViewById(R.id.stopButton);  

  32.         progressbar = (ProgressBar) findViewById(R.id.progressBar);  

  33.           

  34.         //为button绑定onclicklistener  

  35.         startButton.setOnClickListener(new ButtonOnclickListener());  

  36.         stopButton.setOnClickListener(new stopOnclickListener());  

  37.     }  

  38.   

  39.     class ButtonOnclickListener implements OnClickListener{  

  40.         public void onClick(View v) {  

  41.             progressbar.setVisibility(View.VISIBLE);  

  42.             counter = new Thread(){  

  43.                 int i = 1;  

  44.                 @Override  

  45.                 public void run() {  

  46.                     // TODO Auto-generated method stub  

  47.                     i += 10;  

  48.                     Message msg = handler.obtainMessage();  

  49.                     msg.arg1 = i;  

  50.                       

  51.                     //让线程延迟一秒  

  52.                     try {  

  53.                         Thread.sleep(1000);  

  54.                     } catch (Exception e) {  

  55.                         e.printStackTrace();  

  56.                     }  

  57.                     Log.i("run""run "+i+"%");  

  58.                     Log.i("run", Thread.currentThread().getName());  

  59.                     msg.sendToTarget();               

  60.               

  61.                 }  

  62.             };  

  63.             counter.start();  

  64.         }         

  65.     }  

  66.       

  67.     class stopOnclickListener implements OnClickListener{  

  68.         public void onClick(View v) {         

  69.             //从message queue 中去掉run  

  70.             handler.removeCallbacks(counter);  

  71.             //让progressbar置成隐藏  

  72.             progressbar.setVisibility(View.GONE);  

  73.         }         

  74.     }  

  75.       

  76.     //将handler与主线程关联  

  77.     Handler handler = new Handler(looper){  

  78.         public void handleMessage(android.os.Message msg) {  

  79.               

  80.             int i =msg.arg1;  

  81.             //根据message中传来的参数控制进度条  

  82.             progressbar.setProgress(i);  

  83.               

  84.             Log.i("run", Thread.currentThread().getName());  

  85.   

  86.                           

  87.             if(i<100){  

  88.                 handler.post(counter);  

  89.             }else{  

  90.                 handler.removeCallbacks(counter);  

  91.                 progressbar.setVisibility(View.GONE);  

  92.             }  

  93.         };  

  94.     };    

  95. }  


       
         这段代码,和第二篇中最大的差别就是,当我点击启动按钮后,调用的不是主线程的run,而是我新建的线程。

        但是因为安卓不允许我们在主线程之外的线程中对UI进行修改,所以我在新建的线程中只是进行计数,然后将计数的结果通过message传递到主线程中,在主线程中更新进度条。

         


遗留问题:

         本来这个例子到这里就结束了,但是,我为了深入了解一下就在我新建的线程的run中和主线程Handler的handlerMessage方法中打印了当前线程的名称:

结果如下:


        


        按照我最初的理解,在日志中应该是主线程和我的线程交替写入日志,但是实际的情况是在第一次是counter线程,后面打印的都是主线程

        请问各位,有谁知道这是为什么吗?


        我看到在API中Handler的post方法是这么说明的:Causes the Runnable r to be added to the message queue. The runnable will be run on the thread to which this handler is attached.

         难道是,我使用了post方法,就相当于把counter线程的run中的代码拷贝中主线程中去执行了吗?如果有谁知道麻烦为我解答一下,不甚感激!


© 著作权归作者所有

tiansl

tiansl

粉丝 1
博文 17
码字总数 26152
作品 0
成都
私信 提问
Android 3即将发布 Google下周举办发布会

本周早些时候Google发布了Android 3.0蜂巢系统的预览版SDK软件开发工具包,让大家对这款新系统有一个初步的认识。为了让更多人对Android 3有更进一步的认识,Google计划在2月2日举办一次发布...

米狗族
2011/01/30
732
0
Android EditText不弹出输入法总结,焦点问题的总结

看一个manifest中Activity的配置,如果这个页面有EditText,并且我们想要进入这个页面的时候默认弹出输入法,可以这样设置这个属相:android:windowSoftInputMode=stateVisible,这样就会默认...

带梦想一7飞
2013/07/12
363
0
android应用开发简单理解

做了个应用,总结下对于android 应用的简单理解 从上图可以简单看出,主线程启动,这里把各种操作称为action,主要分为3部分: ui(视图绘制)、event(事件处理)和other(数据或网络等处理) 1.当...

blackylin
2013/06/18
649
2
深入理解Android消息处理系统——Looper、Handler、Thread

熟悉Windows编程的朋友可能知道Windows程序是消息驱动的,并且有全局的消息循环系统。而Android应用程序也是消息驱动的,按道理来说也应该提供消息循环机制。实际上谷歌参考了Windows的消息循...

惊天
2011/07/26
726
0
HTC败诉或殃及其他Android手机制造商

新浪科技讯 北京时间7月17日下午消息,美国国际贸易委员会(以下简称“ITC”)周五做出一项初步判决,裁定HTC Android产品侵犯苹果两项专利。分析师认为,这项裁决或许会对其它Android设备制造...

红薯
2011/07/17
1K
6

没有更多内容

加载失败,请刷新页面

加载更多

好程序员大数据教程Scala系列之样例类_Option_偏函数

  好程序员大数据教程Scala系列之样例类_Option_偏函数,在Scala中Option类型样例类用来表示可能存在或也可能不存在的值(Option的子类有Some和None)。Some包装了某个值,None表示没有值。 ...

好程序员官网
4分钟前
0
0
zk中ServerCnxnFactory连接管理工厂

作为ServerCnxn的工厂抽象类 属性 ZOOKEEPER_SERVER_CNXN_FACTORY zookeeper.serverCnxnFactory secure 在ServerCnxnFactory中SSL是否启用 sessionMap session管理配置中信息(sessionId,Ser......

writeademo
5分钟前
0
0
【代码审计01】几种常见的漏洞种类以及代码审计工具

前言 代码审计是在经过黑盒测试完毕,也就是检查应用的基本功能是否符合产品业务需求下进行的。需要有一定的编码基础以及对漏洞形成原理的基本认知,通过工具或者经验检测中代码中可能出现的...

北桥苏
7分钟前
0
0
重磅发布 | 全球首个云原生应用标准定义与架构模型 OAM 正式开源

作者: OAM 项目负责人 导读:2019 年 10 月 17 日,阿里巴巴合伙人、阿里云智能基础产品事业部总经理蒋江伟(花名:小邪)在 Qcon 上海重磅宣布,阿里云与微软联合推出开放应用模型 Open A...

阿里巴巴云原生
8分钟前
0
0
【进阶之定义函数】一个查询树结构数据的集合

1、基本定义 delimiter 自定义符号  -- 如果函数体只有一条语句, begin和end可以省略, 同时delimiter也可以省略create function 函数名(形参列表) returns 返回类型  -- 注意是retru...

卯金刀GG
15分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部