文档章节

android中Handler的初步认识(二)

tiansl
 tiansl
发布于 2015/01/21 15:36
字数 950
阅读 17
收藏 0

  通过第一个小程序,我们对Handler有了一个最基本的认识

    接下来,看一下我们第二个例子

    在第一个例子的基础上,我们假设提出了新的需求:当用户点击启动按钮后,界面上会出现进度条,当进度条到100%后,进度条消失。我们也可以通过取消按钮来取消进度条

    刚看到这个例子的时候,我是这么写的:相对于第一个例子,我在布局文件中加入了一个progressBar的空间,并将它的显示类型默认置成gone

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

  1. <ProgressBar  

  2.     android:id="@+id/progressBar"  

  3.     style="?android:attr/progressBarStyleHorizontal"  

  4.     android:layout_width="fill_parent"  

  5.     android:layout_height="wrap_content"  

  6.     android:visibility="gone" />  


然后activity中这么写的:

[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.Message;  

  7. import android.util.Log;  

  8. import android.view.View;  

  9. import android.view.View.OnClickListener;  

  10. import android.widget.Button;  

  11. import android.widget.ProgressBar;  

  12.   

  13. public class MainActivity extends Activity {  

  14.   

  15.     Button startButton = null;  

  16.     Button stopButton = null;  

  17.     ProgressBar progressbar = null;  

  18.       

  19.     @Override  

  20.     protected void onCreate(Bundle savedInstanceState) {  

  21.         super.onCreate(savedInstanceState);  

  22.         setContentView(R.layout.activity_main);  

  23.           

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

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

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

  27.           

  28.         //为button绑定onclicklistener  

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

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

  31.     }  

  32.   

  33.     class ButtonOnclickListener implements OnClickListener{  

  34.         public void onClick(View v) {  

  35.             //让progressbar显示在界面上  

  36.             progressbar.setVisibility(View.VISIBLE);  

  37.             //将run放入message queue中  

  38.             handler.post(run);  

  39.         }         

  40.     }  

  41.       

  42.     class stopOnclickListener implements OnClickListener{  

  43.         public void onClick(View v) {         

  44.             //从message queue 中去掉run  

  45.             handler.removeCallbacks(run);  

  46.             //让progressbar置成隐藏  

  47.             progressbar.setVisibility(View.GONE);  

  48.         }         

  49.     }  

  50.       

  51.     Runnable run = new Runnable() {  

  52.         int i = 1;  

  53.         @Override  

  54.         public void run() {  

  55.             // TODO Auto-generated method stub  

  56.             i += 10;  

  57.             Message msg = handler.obtainMessage();  

  58.             msg.arg1 = i;  

  59.               

  60.             //让线程延迟一秒  

  61.             try {  

  62.                 Thread.sleep(1000);  

  63.             } catch (Exception e) {  

  64.                 e.printStackTrace();  

  65.             }  

  66.             Log.i("run", "run "+i+"%");  

  67.               

  68.             handler.sendMessage(msg);  

  69.               

  70.             //当progressbar满了之后,停止计数,并隐藏进度条  

  71.             if(i>100){  

  72.                 handler.removeCallbacks(run);  

  73.                 progressbar.setVisibility(View.GONE);  

  74.             }             

  75.         }  

  76.     };  

  77.       

  78.     Handler handler = new Handler(){  

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

  80.               

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

  82.             progressbar.setProgress(msg.arg1);  

  83.             //将run放入message queue中  

  84.             handler.post(run);  

  85.         };  

  86.     };    

  87.   

  88. }  

     然后执行一下,发现刚开始都没问题

一开始的界面是这样:



点击开始按钮之后,进度条出现,并开始变化:


    如果我什么都不错,进度条满了之后,自动消失,我刚开始以为,这样就没问题了,但是当我看控制台的日志时发现,虽然进度条消失了,但是我后台计数动作仍然在执行(如果我点击取消按钮,计数就停止了)



关于这个问题,我在网上查了一下,大家的回答也没有一个十分准确的结论。

     结合网上其他人的解释,加上我自己的理解,我认为是这样的:当前的计数动作是放在message  queue中系统根据队列自动执行的,当运行到run中方法的时候,我调用handler的removeCallBack时,相当于run把自己从队列中 踢掉,这个逻辑显然是不合理的。(如果有知道这个具体原因的麻烦告诉我,这是我自己瞎猜的原因)

    而如果在取消按钮的onclicklistener中调用handler的removeCallBack,相当于从外部把run从队列中去掉,所以可以执行。

    在没有看到更准确的结论之前,我只能这么说服自己了。


    其实这个代码只要简单改一下,就可以实现提前提出的需求了

    把run中的判断改成

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

  1. if(i<100){  

  2.     handler.sendMessage(msg);                 

  3. }else{  

  4.     progressbar.setVisibility(View.GONE);  

  5. }  


    这样只要进度条没满,那么发送message,把run放到队列中。知道进度条满了,在将其隐藏就好了。

    其实这样写,逻辑更加的清楚,也不知道自己第一次写的什么为什么要写得那么别扭,不过我看网上也有很多人出现和我一样的问题。哈哈,大家共勉吧

    到这个例子,我对Handler有了一个初步的认识,但是目前我们的程序还只是在主线程中操作,在下个例子中我将学习handler在多个线程中的应用。


本文转载自:http://blog.csdn.net/xiapinnong/article/details/22579485

tiansl

tiansl

粉丝 1
博文 17
码字总数 26152
作品 0
成都
私信 提问
ViewPager嵌套GridView引发的一系列UI卡顿不顺畅的问题

由于项目要求,需要做一个日历的页面,做法采用ViewPgaer+GridView来做,初步过程很顺利,成型以后,出现UI现象有(1)Acitivity加载时间过长 (2)滑动Viewpager出现卡顿现象; 这两个问题看...

ice_Anson
2013/07/22
7.3K
3
Android手机Wi-Fi及 Wi-Fi直连

> Android WIFI: 当手机成功连接到Wi-Fi热点以后,手机所产生的上网流量都是通过Wi-Fi来传输的,而手机的移动流量会被禁用。但是,我们现在有特殊的业务需求,需要让手机成功连接Wi-Fi后还可...

desaco
03/13
0
0
Android EditText不弹出输入法总结,焦点问题的总结

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

带梦想一7飞
2013/07/12
363
0
Android 3即将发布 Google下周举办发布会

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

米狗族
2011/01/30
732
0
Android Handler 引起的内存泄露

使用Handler导致内存泄露的解决方法 方法一:通过程序逻辑来进行保护。 1.在关闭Activity的时候停掉你的后台线程。线程停掉了,就相当于切断了Handler和外部连接的线,Activity自然会在合适的...

KingMing
2015/04/02
129
0

没有更多内容

加载失败,请刷新页面

加载更多

川普给埃尔多安和内堪尼亚胡的信

任性 https://twitter.com/netanyahu/status/1186647558401253377 https://edition.cnn.com/2019/10/16/politics/trump-erdogan-letter/index.htm...

Iridium
29分钟前
10
0
golang-mysql-原生

db.go package mainimport ("database/sql""time"_ "github.com/go-sql-driver/mysql")var (db *sql.DBdsn = "root:123456@tcp(127.0.0.1:3306)/test?charset=u......

李琼涛
58分钟前
5
0
编程作业20191021092341

1编写一个程序,把用分钟表示的时间转换成用小时和分钟表示的时 间。使用#define或const创建一个表示60的符号常量或const变量。通过while 循环让用户重复输入值,直到用户输入小于或等于0的值...

1李嘉焘1
58分钟前
7
0
Netty整合Protobuffer

现在我们都知道,rpc的三要素:IO模型,线程模型,然后就是数据交互模型,即我们说的序列化和反序列化,现在我们来看一下压缩比率最大的二进制序列化方式——Protobuffer,而且该方式是可以跨...

算法之名
今天
19
0
如何用C++实现栈

栈的定义 栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压...

BWH_Steven
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部