Android上让View自动更新的另一种办法(非线程)
2011-01-29 00:43
309 查看
以前在让使用View时,如果要更新界面,总是使用到线程来更新界面,但在看了SDK之后,发现APIDemo里没有使用过多线程的,使用的是另一个方法。
以前写过一个简单的小游戏,用了View,页面更新的代码如下
这样做看起来很简洁,做在写程序的过程给我造成过一些麻烦,就是线程的生存周期要完全自己来负责,一个不小心的话,当这个Activity的生命周期本应该结束时,这个线程却还一直在后台运行着,相当浪费资源,Android的虚拟机不会主动杀死正在运行中的线程的。如果线程还存在着,却又想新开这个线程,又来抛出错误……还有数据同步的问题等等,这些过程细节都要考虑得周到,不然很容易导致程序被强制关闭。
然而在APIDemo中,在需要不停地重绘界面时,它是在onDraw函数的最后使用了invalidate();
APIDemo的代码请参考Graphics包内的Arcs。
主要的思路如下:
其它部分与以前的无异。这样做的好处是将绘图的线程管理工作全部交给Android来负责(Android本身会有一个线程来专门负责这绘图的),不需要再操心上面所述的问题。如果重绘过程需要有延迟的话,可以使用postInvalidateDelayed (long delayMilliseconds),相当于Thread.sleep(milliseconds)。相当好用,写View的过程少了一些不必要的烦躁。但仍有可能还会有数据的同步问题。但我想可不可以通过Handler,将所以数据的处理全部交给UI线程呢,这样不就将同步问题转得简单点了吗?得我将Handler学得深一点后再实验一下。
这个过程有点类似于尾递归,但又跟递归有实质的区别,invalidate()函数是只是负责发送请求的(在非线程外应使用postInvalidate()),执行函数时,往绘图线程的请求队列增加一个请求,当线程处理这个请求时,就会将界面重绘,这是一个异步的过程,invalidate()并没有执行onDraw,所以并不是递归,没有递归所需的栈,更不用担心爆栈什么的。我上面的代码后面添加了一个log语句,在Logcat里面可以看到有这个main的语句在不停地刷新的。
这里面也涉及到了Android的绘图机制的问题,也就是Handler机制,我现在也只是有一个很模糊的概念,等我学多点后再写出来理清下思路。总的来说,就是Android的绘图是专门由一个线程来负责的,这个线程里有一个请求队列,这个线程会不断地从队列里取出请求来绘制界面,在UI线程外企图修改界面是无效的。
看起来很简单的一句话,涉及的东西不少啊。学无止境。。。。。o(∩∩)o...哈哈
以前写过一个简单的小游戏,用了View,页面更新的代码如下
public void run() { while( drawing ) { try { //更新球的位置信息 update(); //通知系统更新界面,相当于调用了onDraw函数 postInvalidate(); //界面更新的频率,这里是每30ms更新一次界面 Thread.sleep(30); //Log.e(TAG, "drawing"); } catch (InterruptedException e) { e.printStackTrace(); } } }
这样做看起来很简洁,做在写程序的过程给我造成过一些麻烦,就是线程的生存周期要完全自己来负责,一个不小心的话,当这个Activity的生命周期本应该结束时,这个线程却还一直在后台运行着,相当浪费资源,Android的虚拟机不会主动杀死正在运行中的线程的。如果线程还存在着,却又想新开这个线程,又来抛出错误……还有数据同步的问题等等,这些过程细节都要考虑得周到,不然很容易导致程序被强制关闭。
然而在APIDemo中,在需要不停地重绘界面时,它是在onDraw函数的最后使用了invalidate();
APIDemo的代码请参考Graphics包内的Arcs。
主要的思路如下:
public void onDraw(Canvas canvas) { dosomething(); invalidate(); Log.v("main", "invaliate"); }
其它部分与以前的无异。这样做的好处是将绘图的线程管理工作全部交给Android来负责(Android本身会有一个线程来专门负责这绘图的),不需要再操心上面所述的问题。如果重绘过程需要有延迟的话,可以使用postInvalidateDelayed (long delayMilliseconds),相当于Thread.sleep(milliseconds)。相当好用,写View的过程少了一些不必要的烦躁。但仍有可能还会有数据的同步问题。但我想可不可以通过Handler,将所以数据的处理全部交给UI线程呢,这样不就将同步问题转得简单点了吗?得我将Handler学得深一点后再实验一下。
这个过程有点类似于尾递归,但又跟递归有实质的区别,invalidate()函数是只是负责发送请求的(在非线程外应使用postInvalidate()),执行函数时,往绘图线程的请求队列增加一个请求,当线程处理这个请求时,就会将界面重绘,这是一个异步的过程,invalidate()并没有执行onDraw,所以并不是递归,没有递归所需的栈,更不用担心爆栈什么的。我上面的代码后面添加了一个log语句,在Logcat里面可以看到有这个main的语句在不停地刷新的。
这里面也涉及到了Android的绘图机制的问题,也就是Handler机制,我现在也只是有一个很模糊的概念,等我学多点后再写出来理清下思路。总的来说,就是Android的绘图是专门由一个线程来负责的,这个线程里有一个请求队列,这个线程会不断地从队列里取出请求来绘制界面,在UI线程外企图修改界面是无效的。
看起来很简单的一句话,涉及的东西不少啊。学无止境。。。。。o(∩∩)o...哈哈
相关文章推荐
- Android-Handler更新View加线程
- android中的textview显示汉字不能自动换行的一个解决办法
- android ListView/Recyclerview滚动时自动调用onCheckedChanged导致CheckBox状态混乱的解决办法
- Android中不能在子线程中更新View视图的原因
- android 线程更新view及数据传送
- 【Android自学笔记之三】surfaceView更新线程
- android 反纠结app开发: 在线程中更新view
- Mono for android 如何动态添加View,线程内部如何更新UI.
- Android实现TextView走马灯效果同时自动更新显示当前时间
- 子线程更新UI会发生android.view.ViewRoot$CalledFromWrongThreadException异常的解决方法 .
- Android 如何实现带滚动条的TextView,在更新文字时自动滚动到最后一行
- Android 如何实现带滚动条的TextView,在更新文字时自动滚动到最后一行
- android 反纠结app开发: 在线程中更新view
- 子线程更新UI会发生android.view.ViewRoot$CalledFromWrongThreadException异常的解决方法
- android ListView/Recyclerview滚动时自动调用onCheckedChanged导致CheckBox状态混乱的解决办法
- Android新线程中更新主线程UI中的View方法汇总
- 子线程更新UI会发生android.view.ViewRoot$CalledFromWrongThreadException异常的解决方法
- Android 如何实现带滚动条的TextView,在更新文字时自动滚动到最后一行?
- Android新线程中更新主线程UI中的View方法汇总
- android 关于线程更新UI控件,包括gridview,textview,imageview等