2012-01-08 315 views
2

你好在Java和android这里只有几天。我有点困惑究竟是如何“实现Runnable”实际工作的例子:关于“implements 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

看来,在这种情况下,你不想自己实现任何类型的循环。您想要在自定义视图中覆盖onDraw(Canvas canvas)。有了这个,你可以通过在任何地方调用你的视图上的invalidate()来强制onDraw被调用。您也可以接受来自外部来源的参数。

6

implements Runnable的含义是,此类反应在Runnable接口中定义的方法,并为你做那些可以传递给Thread构造。

现在,一个新线程不会立即执行,并且在系统切换到另一个线程的上下文之前,当前线程很可能会继续执行某个函数。

+0

感谢您的快速回复。我意识到线程不保证立即开始。所以我试图用循环和布尔值来锁定我的其他方法,直到run()方法得到执行并且布尔切换。但Run()方法永远不会执行,因此循环无限地继续。对于这个愚蠢的问题抱歉,仍然没有得到它。 – 2012-01-08 05:40:48

+0

尝试使运行isRunning'volatile',并将其值更改为false?我没有在你的代码中看到它。 – MByD 2012-01-08 05:43:36

+0

对不起,我没有复制整个代码。将尝试使其变得不稳定 – 2012-01-08 05:46:41

5

mThread.start();只告诉Java(和OS)使线程有资格运行。不能保证线程将立即开始。事实上,特别是在单核系统上,线程通常不会开始运行直到下一次操作系统跳转并切换任务/线程,因此当它真的开始的时候可能会非常“ ”。

3

Class X ... implements Runnable只做一件事,即承诺X将提供Runnable接口所说的内容。换句话说,这表示X将符合合同,即Java接口(此处为Runnable)。

对于Runnable合同说的唯一的事情就是X会提供一个void run()方法。

这里的技巧是认识到Thread构造函数调用require需要一个Runnable,所以可以肯定有一个run()方法来调用。请注意,当新线程启动时,您的程序现在有两个事件发生的地方。您需要确保正确分配工作,因此它发生在正确的线程中。

2

您对Runnable的理解基本正确。

问题是你对Thread.start()做了什么不正确的假设。实际上,Thread.start()会导致创建新的本地线程及其堆栈,并使线程符合条件运行。但它是执行相关的是否调度新线程,并在start调用返回到原始线程之前运行。

您的代码的另一个问题是run()方法本质上是一个CPU赌博轮询循环。除非你在多核心平台上运行,否则你的应用程序的行为将会非常“迟钝”......并且会迅速耗尽电池。您需要使事件驱动,使用run()方法等待,直到有实际绘制的东西。

我不太了解Android,告诉你如何实现它,但是你的应用程序目前正在做的事情对我来说看起来很不对劲。