Archive for 八月 2010

HDWallPaper Android高清在线壁纸软件

个人对Handler以及Thread的理解

这两天在写个壁纸软件,功能大致是这样:显示一个ProgressBar,再下载图片URL列表,然后根据URL列表逐个下载图片,下载完一张显示一张,直到全部下载完隐藏ProgressBar。
因为之前对Handler理解有误,以为Handler是建立新线程,与UI线程不同,所以所有的操作都放在Handler里,结果上面的功能是实现了,但是UI还是堵塞,在下载图片的过程中,ProgressBar卡住不动。于是请教论坛网友,得知Handler与UI是同一线程的,用Handler下载数据,UI肯定会卡,建议New一个Thread,把下载功能放这里。于是我把所有代码都放进Thread里,结果编译通过,但是执行出错,DDMS里提示android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. (只有原始创建这个视图层次(view hierachy)的线程才能修改它的视图(view)。)。看来notifyDataSetChanged()还是应该放在与UI同线程的Handler里,结果也证明我的猜想是正确的,现在程序已经完美实现我想要的功能。
下面说说我对Handler以及Thread的理解,Handler与UI同线程,它的最主要功能是负责UI与其他进程之间的通讯,而新建一个Thread才是独立于UI的线程,所有耗时操作必须放这里才不致于UI堵塞。

2013年8月26日更新:
不好意思,以上的理解是错误的或者说,不够深入,误导了不少新人,当时写这篇文章的时候,我也是刚接触Android,希望各位见谅.
其实Android是基于消息机制的,通过Looper、Handler来实现消息循环,在线程间相互通讯.Looper里保存了消息列表,通过Handler发送的消息都会保存在Looper里先,然后在loop()方法里,遍历消息列队,分发消息.Handler负责传送消息,处理消息.So,多线程通讯的原理就是,通过另一个线程handler来发送消息,因为Android里主要是跟UI线程通讯,所以一般就在UI线程创建Handler,在工作线程调用这个Handler来发送消息,但并不表示只有UI线程才能有Hanlder,其实要跟UI线程通讯,Handler在哪创建不是重点,重点是,创建这个Handler时使用的Looper对象在哪.
UI线程默认会创建Looper,而工作线程(就是用户自己创建,用于处理耗时操作)默认没有Looper,所以,可以直接在UI线程new Handler,但是在工作线程,需要先调Looper.prepare(),给当前线程创建Looper对象.
如果是调用没有参数的构造方法创建Handler,即new Hanlder(),默认使用的是当前线程的Looper对象.
所以,在工作线程中先Looper.prepare(),再new Hanlder(),这样的Handler是无法与UI线程通讯的.但是Handler还有个带Looper对象参数的构造方法,传入主线程的Looper,另外,Looper类有个静态获取主线程Looper对象的方法:Looper.getMainLooper()
so,在工作线程中创建与UI线程通讯的Handler,可以这样:
Handler mHandler=new Handler(Looper.getMainLooper());
无需再传入UI线程的Looper或者Handler对象作参数.

notifyDataSetChanged() 动态更新ListView 通过 Handler AsyncTask两种方式

有时候我们需要修改已经生成的列表,添加或者修改数据,notifyDataSetChanged()可以在修改适配器绑定的数组后,不用重新刷新Activity,通知Activity更新ListView。今天的例子就是通过Handler AsyncTask两种方式来动态更新ListView.从今天起,每次学习的源代码都会打包上传,方便各位同学学习,注册帐号即可下载。
布局main.xml: Continue reading ‘notifyDataSetChanged() 动态更新ListView 通过 Handler AsyncTask两种方式’ »

Android开发 给音乐播放器加个SeekBar

昨天Android MediaPlayer 一个简单的音乐播放器实例,我们学习了MediaPlayer的初级用法,今天,我们在昨天的基础上,给播放器加个SeekBar,实现显示播放进度,以及快进快退。
先在main.xml里加上个SeekBar, Continue reading ‘Android开发 给音乐播放器加个SeekBar’ »

Android MediaPlayer 一个简单的音乐播放器实例

MediaPlayer,Android内置的一个类,功能同其名,就是媒体播放器。今天我们通过一个简单的例子来学习MediaPlayer用法。
介绍一个最终效果,整个界面就两个Button,一个播放,一个暂停,点击实现相应功能。
布局XML:
Continue reading ‘Android MediaPlayer 一个简单的音乐播放器实例’ »

Android UI设计 Tab TabHost标签页的使用

TabHost广泛运用于android程序中,在程序中运用TabHost,解决了手机屏幕小,显示内容少的问题,如系统自带的拨号程序,就用了TabHost.

分为拨号、通话纪录、联系人、收藏几个Tab。
先看今天学习的例子的最终效果。
Continue reading ‘Android UI设计 Tab TabHost标签页的使用’ »

AsyncTask用法实例 用AsyncTask更新进度条ProgressBar(防止UI线程阻塞)

AsyncTask直译为异步任务,顾名思义,就是跟UI线程不同步,相对于UI来说是另一个线程,跟Handler类似,可以在后台执行任务,然后根据执行结果更新UI。今天这个例子以更新进度条ProgressBar为例,前面有过一篇通过Handler更新ProgressBar的笔记,感兴趣的朋友可以看看区别。效果就不传图片了,反正就是那样,就是一进度条进度不停地增加,还有一个TextView显示当前进度值(0-100),执行完会在标题栏提示“执行完毕”。
先是布局xml: Continue reading ‘AsyncTask用法实例 用AsyncTask更新进度条ProgressBar(防止UI线程阻塞)’ »

GridView自动下载并显示网络图片

关于GridView的使用请查看上一篇文章Android UI设计 图片列表GridView用法,本文讲的是在上一篇文章的基础上实现自动下载显示网络上的图片。
布局XML代码不需要修改,程序代码也基本一致,只要稍稍修改下图片适配器就可以了。
Continue reading ‘GridView自动下载并显示网络图片’ »