`

post postinvalidate invalidate

 
阅读更多

android

Handler.post(action) 这是android提供的一种机制,handler对象将通过post方法,将里面的Runnable对象放到UI执行队列中,UI消费这个队列,调用Runnable的run方法。这里并不生成新的线程。

 

  Android中在绘图中的多线程中,invalidate和postInvalidate这两个方法是用来刷新界面的,调用这两个方法后,会调用onDraw事件,让界面重绘。

 

 

在一个没有使用线程的小游戏中想刷新一下时间进度,想到用Timer。于是写了一段代码:

 

        nStartRoundTime = System.currentTimeMillis();
        nT1 = new Timer();
        nT1.schedule(new TimerTask(){ //计划运行时间间隔
                public void run(){
                    refreshTimePaint(); //过3秒调用一下refreshTimePaint()
                }
              },0,3000);

 

 

 

    public void refreshTimePaint(){
        invalidate(); //使用invalidate();刷新
        System.out.println(System.currentTimeMillis());
        System.out.println(nGameState);
    }

 

    同时我也将System.currentTimeMillis()打印在View上。

 

运行一下,发现并不是预期那样, System.out.println的结果在Log里面都有变化,但是View却没有反应。 不但View上面没有被刷新,甚至连原来的触屏事件都没有反映了。

 

去网上查了一下,得到的一些解释有这些:

 

The best thing is to  use Handler with delayed messages.
And Timer works fine, the problem is that a Timer runs in a separate thread,   and so you are trying to modify a view owned by another thread (the main   thread that originally created it).

 

 

What I think is happening is you're falling off the UI thread. There is a single "looper" thread which handles all screen updates. If you attempt to call "invalidate()" and you're not on this thread nothing will happen.

Try using "postInvalidate()" on your view instead. It'll let you update a view when you're not in the current UI thread.

 

于是把refreshTimePaint()的代码改成:

 

public void refreshTimePaint(){
        this.postInvalidate(); //使用postInvalidate();刷新
        System.out.println(System.currentTimeMillis());
        System.out.println(nGameState);
    }

 

 

这样View就能自动刷新了~~~

 

这里有几个网页做参考:

http://stackoverflow.com/questions/522800/android-textview-timer

http://groups.google.com/group/android-developers/browse_thread/thread/5baf5a3eaa823b7b?pli=1

http://groups.google.com/group/android-developers/msg/f5765705b8c59d66

分享到:
评论

相关推荐

    android中Invalidate和postInvalidate的更新view区别

    Android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用,感兴趣的朋友可以了解下哦

    Android中invalidate()和postInvalidate() 的区别及使用方法

    Android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。本文给大家介绍Android中invalidate()和postInvalidate() 的区别及使用...

    浅谈Android invalidate 分析

    1. invalidate 和 postInvalidate 的关系 postInvalidate 是通过 Handler 切换回到主线程,然后在调用 invalidate 的,源码: public void postInvalidate() { postInvalidateDelayed(0); } public void ...

    Android 实现界面刷新的几种方法

    Android程序中可以使用的界面刷新方法有两种,分别是利用Handler和利用postInvalidate()来实现在线程中刷新界面。 利用Handler刷新界面 实例化一个Handler对象,并重写handleMessage方法调用invalidate()实现界面...

    Android中刷新界面的二种方法

    Android界面刷新方法有两种,分别是利用Handler和利用postInvalidate()来实现在线程中刷新界面。 利用Handler刷新界面 实例化一个Handler对象,并重写handleMessage方法调用invalidate()实现界面刷新;而在线程中...

    android 快速翻书

    照比較正常的作法, 如果不是做Game之類的應該通常會新增thread處理工作後, 使用handler傳送msg去View#invalidate畫面, 或是在非UI thread呼叫View#postInvalidate. 所以如果需要比較高效的畫面更新就可以用看看...

    10编写推箱子游戏程序(第五步)

    本文是系列文章第十篇,讲如何实现下述功能:玩家用手指触摸屏幕来指挥搬运工走动。你将学到的知识内容:  1. 利用回调函数onTouchEvent处理屏幕触摸事件。... 2. 利用invalidate或postInvalidate方法刷新视图。

    Android-UI刷新

    Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。 Android程序中可以使用的界面刷新...

    Android-LinearLayout-Parser:为所有孩子和子孩子解析一个 Android LinearLayout 对象

    但是在根布局上调用 invalidate 或 postInvalidate 不会自动强制子级重新绘制自己。 因此,每个孩子都需要调用 postInvalidate。 ModDataLLParser 可以从活动的 OnCreate 方法实例化。 它应该在视图初始化之后完成...

    android hanoi 汉诺塔源码

    android hanoi 汉诺塔源码 postInvalidate PreferenceActivity SharedPreferences

    android开发教程之handler异步更新ui

    调用Handler.post(Runnable r)方法,Runnable运行在UI所在线程,所以可以直接调用View.invalidate() 代码如下:packagecom.Test.androidtest; importandroid.app.Activity;importandroid.content.Context;importandroid...

    Android 自动翻页-文字自动换行的例子.rar

    Android 自动翻页-文字自动换行的例子,...触笔事件、线程处理、绘制字符串、翻页等按键处理,在线程处理中,使用postInvalidate可以直接在线程中更新界面。  比较基础的例子了,相信Android新同学会喜欢这个源码。

    Android 自定义CircleProgress 圆形、圆环进度条.rar

    我们需要根据字体的宽度设置在圆环中间,中间的进度百分比,先转换成float在进行除法运算,不然都为0,设置进度时,由于考虑多线的问题,需要同步刷新界面调用postInvalidate()能在非UI线程刷新。  本源码中的注释...

    自定义控件

    基本原理,android自定义控件,onDraw,canvas:画布 Paint:画笔,获取屏幕尺寸:DisplayMetrics,postInvalidate();//强制刷新,不等待队列

    【Android】自定义圆形进度条效果(有进度标识点)

    this.postInvalidate(); } /** * 进度标注点的动画 * * @param fromDegrees * @param toDegrees * @return */ private Animation pointRotationAnima(float fromDegrees, float toDegrees) { int ...

    android源码连连看

    gameView.postInvalidate(); } else { gameView.setLinkInfo(linkInfo); gameView.setSelectedPiece(null); gameView.postInvalidate(); pieces[piece.getIndexX()][piece.getIndexY()...

    XMultiColumnListView

    postInvalidate(); invokeOnScrolling(); } super.computeScroll(); } @Override public boolean onTouchEvent(MotionEvent ev) { if (mLastY == -1) { mLastY = ev.getRawY(); } switch ...

    动态圆弧进度条

    this.postInvalidate(); } } 上面的代码就是画两个圆弧 package com.example.task; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View....

Global site tag (gtag.js) - Google Analytics