我目前在從不在我的主用戶界面上的線程繪製自定義SurfaceView
時遇到問題。此SurfaceView
佔用整個屏幕(全屏Galaxy S3),並且必須從多個來源更新。如何使用單獨的線程部分重繪自定義SurfaceView而不會丟失先前的編輯?
問題是自定義SurfaceView
不會保存UI更新之間的更改。
自定義SurfaceView
類被定義在使用它的活動中,並且在自定義SurfaceView
類中定義了定期檢查更新的線程(我們稱之爲DrawingThread
)。我已經做了類似於this tutorial。
另一個外部線程正在更新必須對UI進行的更改列表。 DrawingThread
每50ms左右檢查一次該列表,如果列表不爲空,則計算一個必須重繪的矩形。
// Thread waits for change request to UI or kill order
// Build Rect at point of Touch
try {
Canvas = _surfaceHolder.lockCanvas(Rect);
synchronized (_surfaceHolder) {
postInvalidate(); //Calls custom SurfaceView's onDraw() with the correct Canvas
}
} finally {
if (Canvas != null) {
_surfaceHolder.unlockCanvasAndPost(Canvas);
}
}
// Loop
我onDraw()
自定義SurfaceView
方法如下:
@Override
public void onDraw(Canvas canvas) {
// Initialize vars for rectangle
Paint.setStyle(Style.FILL);
for (MapChanges change : ExternalClass.getMapChanges()) {
// Build Rect at point of Touch
// Select Color for Paint
canvas.drawRect(Rect, Paint);
ExternalClass.removeMapChange(change); //Thread safe
}
}
這完美的作品,除了一個事實,即它是忘記從以前onDraw()
通話的變化。我目前正在使用OnTouchListener
進行測試。
代碼的程序,我的理解是:
- 觸摸增加了對UI在
ExternalClass
列表中的更改請求。 DrawingThread
看到列表不再爲空,安全地抓住畫布,並且postInvalidates()
調用自定義SurfaceView
的onDraw()
。onDraw()
更新UI並從ExternalClass
中刪除更改請求。DrawingThread
發帖Canvas
並返回等待。
我的預期行爲是我會連續觸摸在屏幕上累積點。相反,每次觸摸都會清除屏幕,讓我留下背景,並在上次觸摸屏幕時留下一個點。
我覺得這很容易混淆,因爲lockCanvas(Rect)
明確提到它會通過指定「髒」部分來保存鎖之間的更改。 Google搜索讓我相信大多數用戶會發現相反的問題:他們希望重繪View
,但必須手動更新每次更新。
爲什麼程序從頭開始繪製一個乾淨的SurfaceView
每個UI更新,儘管我指定了一個「髒」部分來重繪?
毫無疑問,有人會引用我到this previously answered question,程序員被建議使用位圖。我試圖避免這種情況,這是因爲我對此有多新,以及我的願望是不能處理大量內存(更新UI僅僅是我的代碼的一小部分)。直接在View
上使用簡單的形狀對我來說很理想。此外,它作爲解決方法呈現。這是Android API的一個缺陷嗎?
已經在這裏搜索和Google幾個小時了。希望我沒有錯過任何明顯的東西。