invalidate()是用来刷新屏幕更新View的,必须是在主线程中进行工作.因为它属于更新UI. 比如在修改某个View的显示时,调用invalidate()才能看到重新绘制的界面,invalidate()的调用就是把之前的旧View中从主UI线程队列中pop掉.
对于屏幕刷新有以下3种情况:
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.
其意思就是子线程不能更新Ui.这个时候.需要创建一个继承了android.os.Handler的子类,并重写handleMessage(Message msg)方法. android.os.Handler是能发送和处理消息的,你需要在Activity中发出更新UI的消息,然后在你的Handler(可以使用匿名内部类)中处理消息(因为匿名内部类可以访问父类变量,你可以直接使用View对象调用View的invalidate()方法.).也就是说:在新线程中创建并发送一个Message,然后再主线程中捕获,处理该消息.
3. 使用双线程和双缓冲
Android中SurfaceView是View的子类,它同时也实现了双缓冲, 你可以定义一个它的子类并实现SurfaceHandler.Callback接口.由于实现SurfaceHolder.Callback接口,新线程就不需要android.os.Handler来帮忙了.SurfaceHolder.Callback中lockCanvas()方法可以锁定画布.绘制完新的图像后调用unlockCanvasAndPost(canvas)解锁(显示).还是还是比较方便的.