2011-05-16 13 views
6

मैं एक SurfaceView उपclass लागू कर रहा हूँ, जहां मैं एक SurfaceHolders कैनवास पर आकर्षित करने के लिए एक अलग धागा चलाते हैं। मैं lockCanvas() पर कॉल करने से पहले और बाद में समय माप रहा हूं, और मुझे लगभग 70ms से 100ms तक मिल रहा है। क्या कोई मुझे इंगित कर सकता है कि मुझे इतना ऊंचा समय क्यों मिल रहा है? यहाँ कोड के प्रासंगिक भाग:लॉक कैनवास() धीमा क्यों है?

public class TestView extends SurfaceView implements SurfaceHolder.Callback { 

.... 

boolean created; 
public void surfaceChanged(SurfaceHolder holder, int format, int width, 
      int height) { 

    mThread = new DrawingThread(mHolder, true); 
    mThread.onWindowResize(width, height); 
    mThread.start(); 
} 

public void surfaceCreated(SurfaceHolder holder) { 

    created = true; 
} 

public void surfaceDestroyed(SurfaceHolder holder) { 
    created = false; 

} 
class DrawingThread extends Thread { 
public void run() { 
while(created) { 



      Canvas canvas = null; 
      try { 
          long t0 = System.currentTimeMillis(); 
      canvas = holder.lockCanvas(null); 
      long t1 = System.currentTimeMillis(); 
          Log.i(TAG, "Timing: " + (t1 - t0)); 
      } finally { 
       holder.unlockCanvasAndPost(canvas); 
      } 
} 

उत्तर

1

इस पढ़ें:

What does lockCanvas mean (elaborate)

+0

ठीक है, धन्यवाद। मैंने पहले ही इसे पढ़ लिया है, और अवधारणाओं को समझ लिया है। लेकिन मुझे अभी तक कोई समाधान नहीं मिला है। भले ही मैं 'सिंक्रनाइज़' ब्लॉक को हटा दूं (जिसे अनुशंसित नहीं किया गया है), यह मेरी मदद नहीं करता है। अभी भी उन उच्च समय। – kaneda

4

आप एक धागा हर बार सतह बदल जाता है बना रहे हैं। आपको अपना धागा surfaceCreated में शुरू करना चाहिए और surfaceDestroyed में इसे मारना चाहिए। surfaceChanged तब होता है जब आपकी सतह के आयाम बदलते हैं।

SurfaceView से। surfaceCreated दस्तावेज़:

सतह को पहली बार बनाए जाने के तुरंत बाद इसे तुरंत कहा जाता है। इसके कार्यान्वयन चाहे जो भी प्रतिपादन कोड चाहते हैं, शुरू करें। ध्यान दें कि केवल एक थ्रेड किसी सतह में खींचा जा सकता है, इसलिए यदि आपका सामान्य प्रतिपादन किसी अन्य धागे में होगा तो आपको सतह में नहीं खींचना चाहिए।

एकाधिक धागे शायद आपको थ्रॉटल कर रहे हैं। SurfaceHolder से। lockCanvas डॉक्स:

आप इस बार-बार फोन जब सतह तैयार नहीं है (Callback.surfaceCreated से पहले या Callback.surfaceDestroyed के बाद), तो अपने कॉल एक धीमी दर करने के लिए आदेश लेने वाली सीपीयू से बचने के लिए रोक दिए दिया जाएगा।

हालांकि, मुझे विश्वास नहीं है कि यह एकमात्र समस्या है। surfaceChanged वास्तव में कई बार बुलाया जाता है?

+0

जब दस्तावेज़ कहते हैं कि 'केवल एक धागा कभी सतह पर खींचा जा सकता है' ... क्या यह कथन अंकित मूल्य पर लिया जाना चाहिए, या वे कह रहे हैं "... एक ही समय में एक सतह * में आकर्षित हो सकता है *"। –

+1

मुझे लगता है कि इसे अंकित मूल्य पर लिया जाना चाहिए। यहां तक ​​कि यदि नहीं, तो आपको अपने ड्रा कमांड को क्रमबद्ध करना होगा। (शायद यही कारण है कि उन्हें आपको एक थ्रेड पर सबमिट करने की आवश्यकता क्यों है।) Http://stackoverflow.com/a/11258546/79125 के अनुसार मैं सही हूं (लेकिन हम इंटरनेट पर केवल दो लोग हैं;)। – idbrii

+0

ओह। मैं निश्चित रूप से एक अच्छा ट्यूटोरियल का शौकिया हूं (जो कि प्रतिक्रिया लिंक)। धन्यवाद। काश मैं उस के लिए आपको दो +1 दे सकता हूं =) –

1

यह lockCanvas से संबंधित है और वास्तव में एंड्रॉइड ग्राफिक ढांचे में लागू किया गया है।

आपको शायद पहले से ही पता होना चाहिए कि lockCanvas आपको मुफ्त मेमोरी का टुकड़ा देगा जिसे आप आकर्षित करने के लिए उपयोग करेंगे। द्वारा, इसका मतलब है कि इस स्मृति का उपयोग रचना के लिए नहीं किया गया है, न कि प्रदर्शन के लिए। आंतरिक रूप से, बस बोलते हुए, एक SurfaceView का समर्थन डबल बफर द्वारा किया जाता है, एक ड्राइंग के लिए होता है, एक रचना/प्रदर्शन के लिए होता है। यह डबल बफर BufferQueque द्वारा प्रबंधित किया जाता है। यदि चित्र/प्रदर्शन ड्राइंग से धीमा है, तो हमें तब तक इंतजार करना होगा जब तक कि हमारे पास मुफ्त बफर उपलब्ध न हो।

संबंधित मुद्दे