2012-01-08 224 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,告訴你如何實現它,但是你的應用程序目前正在做的事情對我來說看起來很不對勁。