Android开发:Invalidate和postInvalidate刷新View的区别及应用-----ImageView绘制旋转圆环(二)...

本文主要是介绍Android开发:Invalidate和postInvalidate刷新View的区别及应用-----ImageView绘制旋转圆环(二)...,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

上文 已经实现了圆环旋转,但是很多合格。发现之前对handler Thread Runnable理解的不深,包括如何刷新UI。这次总算清了一下帐,基本搞清除了。Android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。参考这里,刷新UI有三种方式:

1.不使用多线程和双缓冲

这种情况最简单了,一般只是希望在View发生改变时对UI进行重绘。你只需在Activity中显式地调用View对象中的invalidate()方法即可。系统会自动调用 View的onDraw()方法。

2.使用多线程和不使用双缓冲

这种情况需要开启新的线程,新开的线程就不好访问View对象了。强行访问的话会报:android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.

这时候你需要创建一个继承了android.os.Handler的子类,并重写handleMessage(Message msg)方法。android.os.Handler是能发送和处理消息的,你需要在Activity中发出更新UI的消息,然后再你的Handler(可以使用匿名内部类)中处理消息(因为匿名内部类可以访问父类变量, 你可以直接调用View对象中的invalidate()方法 )。也就是说:在新线程创建并发送一个Message,然后再主线程中捕获、处理该消息。

3.使用多线程和双缓冲

Android中SurfaceView是View的子类,她同时也实现了双缓冲。你可以定义一个她的子类并实现SurfaceHolder.Callback接口。由于实现SurfaceHolder.Callback接口,新线程就不需要android.os.Handler帮忙了。SurfaceHolder中lockCanvas()方法可以锁定画布,绘制玩新的图像后调用unlockCanvasAndPost(canvas)解锁(显示),还是比较方便得。

上面清晰也可以看到SurfaceView绘图和一般ImageView绘图的区别。一般采用第二种,个人觉的第二种里还是采用postInvalidate的方法好。因为invalidate是在主UI线程里,容易卡。尤其在退出程序的时候,这个很明显。所以刷新ImageView,让圆环转起来,我采用的是postInvalidate方法。

代码如下:
class UpdateThread implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}

// 使用postInvalidate可以直接在线程中更新界面

postInvalidate();
}
}
}

注意这个postInvalidate(); 当执行这句话时,ImageView会自动调用onDraw()一次。在protected void onDraw(Canvas canvas) { }里进行画图就Ok了。正基于此,postInvalidate()这句话放在Thread.sleep(100);后面也是可以的,感觉这样反而更容易理解!在DrawImageView的构造函数里调用new Thread(new UpdateThread()).start()开启这个刷新线程。

另外,还有一点这种方式是定义一个UpdateThread,还可以直接在申请类的时候就实现这个接口如public class DrawImageView extends ImageView implements Runnable{},这样做的好处就是变量的申明和定义上。

举个例子,像http://blog.csdn.net/hui_ttoo/article/details/5390387这里提供的第二段示例程序:

class CustomizeView extends TextView {public CustomizeView(Context context) {super(context);new Thread(new UIUpdateThread()).start();}class UIUpdateThread implements Runnable {final Handler mHandler = new Handler();final Runnable mUpdateResults = new Runnable() {public void run() {concreteUpdateUI();invalidate();}};public void run() {// delay some minutes you desire. /*try {Thread.sleep(1000 * 5);} catch (InterruptedException e) {e.printStackTrace();}*/mHandler.post(mUpdateResults);}}protected void concreteUpdateUI() {// Add concrete movement for UI updates.  // ...  }}

里面没有重载onDraw()函数,而是自己新建一个刷新Ui的函数,这个函数可以获取TextView然后更新时间阿。如果既有自己定义的updateUi又重载了onDraw()函数。由于updateUI是类UIUpdateThread 里面的子函数,如果不作处理,是无否调用全局的View成员。

但我不推荐上面这种写法,上面这种写法在线程中止时很可能会有问题。如果是用invalidate方法更新UI,我推荐这种写法:

// 在onCreate()中开启线程new Thread(new GameThread()).start();、// 实例化一个handlerHandler myHandler = new Handler() {
// 接收到消息后处理
public void handleMessage(Message msg) {
switch (msg.what) {
case Activity01.REFRESH:
mGameView.invalidate(); // 刷新界面
break;
}super.handleMessage(msg);
}
};class GameThread implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
Message message = new Message();
message.what = Activity01.REFRESH;
// 发送消息
Activity01.this.myHandler.sendMessage(message);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}}
参考:

http://www.cnblogs.com/tt_mc/archive/2012/01/30/2332023.html

http://www.blogjava.net/gooogle/archive/2008/03/05/184030.html

http://pwp5566.iteye.com/blog/1473159

http://kalogen.iteye.com/blog/1566111

http://blog.csdn.net/hui_ttoo/article/details/5390387 (前两个比较好)






这篇关于Android开发:Invalidate和postInvalidate刷新View的区别及应用-----ImageView绘制旋转圆环(二)...的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/260177

相关文章

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

基于Python开发PPTX压缩工具

《基于Python开发PPTX压缩工具》在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,不便于传输和存储,所以本文将使用Python开发一个PPTX压缩工具,需要的可以了解下... 目录引言全部代码环境准备代码结构代码实现运行结果引言在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,

css实现图片旋转功能

《css实现图片旋转功能》:本文主要介绍了四种CSS变换效果:图片旋转90度、水平翻转、垂直翻转,并附带了相应的代码示例,详细内容请阅读本文,希望能对你有所帮助... 一 css实现图片旋转90度.icon{ -moz-transform:rotate(-90deg); -webkit-transfo

数据库使用之union、union all、各种join的用法区别解析

《数据库使用之union、unionall、各种join的用法区别解析》:本文主要介绍SQL中的Union和UnionAll的区别,包括去重与否以及使用时的注意事项,还详细解释了Join关键字,... 目录一、Union 和Union All1、区别:2、注意点:3、具体举例二、Join关键字的区别&php

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤

java中的HashSet与 == 和 equals的区别示例解析

《java中的HashSet与==和equals的区别示例解析》HashSet是Java中基于哈希表实现的集合类,特点包括:元素唯一、无序和可包含null,本文给大家介绍java中的HashSe... 目录什么是HashSetHashSet 的主要特点是HashSet 的常用方法hasSet存储为啥是无序的

5分钟获取deepseek api并搭建简易问答应用

《5分钟获取deepseekapi并搭建简易问答应用》本文主要介绍了5分钟获取deepseekapi并搭建简易问答应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1、获取api2、获取base_url和chat_model3、配置模型参数方法一:终端中临时将加