[英]Android SurfaceView, OnDraw called but display is not updating without invalidate()
I'm having a little trouble following a typical Android graphics flow. 我在跟踪典型的Android图形流程时遇到了一些麻烦。 There are many examples but mine seems not to work.
有很多例子,但我的似乎没有用。 In my main activity I do this:
在我的主要活动中,我这样做:
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
In my resources file I have 3 custom classes that override SurfaceView. 在我的资源文件中,我有3个覆盖SurfaceView的自定义类。 In my constructor for these Surface Views I have something like this:
在我对这些Surface Views的构造函数中,我有这样的东西:
super(context, attrs);
getHolder().addCallback(this);
this.thread = new MyThread(getHolder(),this);
In my thread's run method I do this (lifted from many examples I've seen): 在我的线程运行方法中,我这样做(从我见过的许多例子中解除):
Canvas c;
try {
c = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
panel.onDraw(c);
}
} finally {
if (c != null) {
surfaceHolder.unlockCanvasAndPost(c);
}
This thread is started in my SurfaceView's 'surfaceCreated' event. 该线程在我的SurfaceView的'surfaceCreated'事件中启动。 In onDraw I do this:
在onDraw中我这样做:
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
<some drawing stuff here using canvas>
}
When I run, the thread does indeed run, and I can see that onDraw is getting called (I put log print command in there), however my graphics don't update as expected. 当我运行时,线程确实运行,我可以看到onDraw被调用(我在那里放了日志打印命令),但是我的图形没有按预期更新。 If I call this.invalidate(), however, the graphics do update a handful of times as I expect until I crash with this:
但是,如果我调用this.invalidate(),图形确实会像我预期的那样更新几次,直到我崩溃为止:
E/AndroidRuntime(748): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
I realize according the examples I've seen I shouldn't need to call invalidate in OnDraw, but I did it just to verify that the code in my onDraw is valid. 我根据我看到的示例意识到我不应该在OnDraw中调用invalidate,但我只是为了验证我的onDraw中的代码是有效的。 So, it seems to me that without the invalidate() the onDraw event is getting called, and my code should be updating the graphics properly, but the screen never updates.
所以,在我看来,没有invalidate()onDraw事件被调用,我的代码应该正确更新图形,但屏幕永远不会更新。 I'm missing something in how the main Activity actually decides that it needs to repaint it's children.
我错过了主要活动如何确定它需要重新绘制它的孩子的东西。
Any ideas would be greatly appreciated. 任何想法将不胜感激。 I've spent a while trying to copy stuff from some working demos but I just seem to be stuck.
我花了一段时间试图从一些工作演示中复制一些内容,但我似乎陷入困境。 Thanks
谢谢
the stuff you do in run() does whatever you do - Once. 你在run()中所做的事情会做你做的任何事情 - 一次。 You need to repeat the drawing process.
您需要重复绘图过程。
One way could be to put everything inside a while
loop 一种方法是将所有内容放在
while
循环中
while(true){
try {
c = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
panel.onDraw(c);
}
} finally {
if (c != null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
I already had the same problem. 我已经遇到了同样的问题。 As I could not find any solution, I did a kind of workaround: Create a
Bitmap
as a buffer and draw to that bitmap. 由于我找不到任何解决方案,我做了一种解决方法:创建一个
Bitmap
作为缓冲区并绘制到该位图。 After drawing, draw the complete bitmap to the view itself. 绘制后,将完整的位图绘制到视图本身。 Declare these variables in your View class:
在View类中声明这些变量:
Canvas bmpCanvas;
Bitmap bmp;
And use it in your onDraw()-method like shown: 并在你的onDraw()中使用它 - 如下所示的方法:
@Override
protected void onDraw(Canvas canvas) {
if(bmp == null || bmpCanvas == null) {
bmp = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
bmpCanvas = new Canvas(bmp);
}
//do drawing-stuff here
canvas.drawBitmap(bmp, 0, 0, p); //where p is a Paint-Object.
}
Now, to update the view/call this method use either invalidate
or postInvalidate()
invalidate
of your view, depending on whether you call the method in the same thread or in an other thread. 现在,要更新视图/调用此方法,请使用
invalidate
或postInvalidate()
invalidate
视图invalidate
,具体取决于您是在同一线程还是在其他线程中调用该方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.