你好,Java和android只有几天了。我对“实现runnable”实际上是如何工作的例子感到有点困惑:
public class DrawableSurfaceView extends SurfaceView implements Runnable {
[...]
public void resume(){
isRunning = true;
mThread = new Thread(this);
mThread.start(); //start the animation
parseParameters(); //<== Here is my problem
}
public void run() {
while (isRunning == true){
if (!mHolder.getSurface().isValid()) {
continue;
}
Canvas canvas = mHolder.lockCanvas();
canvas.drawARGB(255, 0, 0, 0);
canvas.drawPath(PenPath, PenPaint);
canvas.drawPath(CursorPath, CursorPaint);
mHolder.unlockCanvasAndPost(canvas);
}
}
public void parseParameters() {
[...]
[ The rest of my code here modifying PenPath and CursorPath, etc ]
}
我很尴尬地问,但我想在mThread.start()之后;将在run方法中开始运行循环的新线程。而我得到的是仅在我的parseParameters()方法终止后执行的run方法。 我想要实现的是将画布放在绘图循环线程上,并从外部修改绘图路径的参数以生成我的动画。 我确信这是非常基本的,但我几个小时都无法理解这一点。文档没有帮助。
任何指针都会有很大帮助。干杯啦!
答案 0 :(得分:6)
implements Runnable
的含义是此类对Runnable接口中定义的方法作出反应,并且可以像那样将它们传递给Thread
的构造函数。
现在,没有立即执行新线程,并且当前线程很可能会在系统切换到其他线程的上下文之前继续执行某些功能。
答案 1 :(得分:5)
mThread.start();
只告诉Java(和操作系统)使线程有资格运行。无法保证线程会立即启动。事实上,特别是在单核系统上,线程通常不会开始运行,直到下一次操作系统跳入并切换任务/线程,所以当它实际启动时可能非常“当它感觉就像它”
答案 2 :(得分:3)
Class X ... implements Runnable
只做一件事,即承诺X将提供Runnable接口所说的内容。换句话说,它表明X将符合契约一个Java接口 - 这里是Runnable - 。
对于Runnable
合同唯一说的是,X将提供void run()
方法。
这里的技巧是识别调用的Thread
构造函数需要一个Runnable,因此可以确定有一个run()
方法可以调用。请注意,当新线程启动时,您的程序现在有两个位置。您需要确保正确分配工作,因此它发生在正确的线程中。
答案 3 :(得分:2)
您对Runnable
的理解基本上是正确的。
问题在于您对Thread.start()
的作用做出了错误的假设。实际上,Thread.start()会导致创建新的本机线程及其堆栈,并使线程符合条件运行。但是实现依赖新线程是否已调度并在start
调用返回原始线程之前运行......或者不是。
您的代码的另一个问题是run()
方法本质上是一个CPU吞噬轮询循环。除非您在具有多个内核的平台上运行,否则您的应用程序的行为将非常“滞后”......并且它将迅速耗尽电池。您需要使用run()
方法进行事件驱动,直到有实际绘制的内容为止。
我不太了解Android如何实现这一点,但您的应用目前正在做的事情对我来说是非常错误的。
答案 4 :(得分:0)
在这种情况下,您似乎不希望自己实现任何类型的循环。您可能希望覆盖自定义视图中的onDraw(Canvas canvas)。有了这个,您可以通过从任何地方调用视图上的invalidate()来强制调用onDraw。您也可以接受外部来源的参数。