2016-11-22 12 views
12

उपयोग मामला:बुरा प्रदर्शन जब CustomView में लगातार ड्राइंग

मैं सौ लाइनों और मेरे विचार पर पाठ के कुछ टुकड़ों आकर्षित करने के लिए की जरूरत है। मुझे स्क्रॉलिंग प्रभाव देने की ज़रूरत है, जिसके लिए मैं ACTION_MOVE ईवेंट कैप्चर करता हूं और अद्यतन बिंदुओं के साथ सभी लाइनों को दोबारा हटा देता हूं। इच्छा परिणाम प्राप्त करने के लिए मैंने विभिन्न दृष्टिकोणों के साथ प्रयास किया लेकिन कोई भी उद्देश्य के रूप में काम नहीं करता है।

दृष्टिकोण 1

मैं जो View फैली एक कस्टम वर्ग बनाया है। सभी ड्राइंग और गणना सीधे मेरे onDraw() विधि में की जाती है। चूंकि onDraw() विधि में बहुत अधिक ऑपरेशन किया गया है, इसलिए ऐप का प्रदर्शन बहुत खराब है। मैंने प्रोफाइल GPU प्रतिपादन का उपयोग करके प्रदर्शन की भी जांच की और मैं देख सकता हूं कि रेखाएं बहुत लंबी हैं।

दृष्टिकोण 2

मैं एक बिटमैप बनाई गई और एक अन्य सूत्र में मेरी बिटमैप पर सभी लाइनों ड्राइंग के बाद, मैं postInvalidate() इस्तेमाल किया onDraw() विधि में बिटमैप आकर्षित करने के लिए:

mBufferedBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); 
mBufferedBitmap.eraseColor(Color.TRANSPARENT);  
Canvas mBufferedCanvas = new Canvas(mBufferedBitmap);    
drawLines(mBufferedCanvas)  
postInvalidate(); 

के बाद से मैं मिटा बिटमैप पर सभी पिछली ड्राइंग और अपडेटेड पॉइंट्स के साथ नई लाइनें खींचें, स्क्रीन पर एक झटके लग रही हैं।

दृष्टिकोण 3

मैं SurfaceView को अपने कस्टम वर्ग का विस्तार और एक अन्य सूत्र में कैनवास वस्तु पर सभी ऑपरेशनों को करने की कोशिश की। लेकिन चूंकि SurfaceView ड्रॉइंग ऑपरेशंस के लिए CPU का उपयोग करता है, तो प्रदर्शन कम कॉन्फ़िगरेशन मोबाइल में खराब होगा।

क्या कोई मुझे बेहतर प्रदर्शन के साथ इस कार्य को प्राप्त करने के लिए मार्गदर्शन कर सकता है?

+0

[ 'RenderScript'] में देख (प्रयास करें https://developer.android.com/guide/topics/renderscript/ compute.html)। मैंने स्वयं ढांचे का उपयोग नहीं किया है, लेकिन यह इसके लिए एक अच्छा उपयोग-मामला जैसा लगता है। – Bryan

+0

मेरे उपयोग के मामले में रेंडरस्क्रिप्ट की आवश्यकता नहीं होगी। – VijayRaj

+4

'ऑनड्रा()' में नया बिटमैप आवंटित न करें, यही कारण है कि आपके पास fps ड्रॉप है। –

उत्तर

7

अच्छा प्रदर्शन प्राप्त करने के लिए अपने दृष्टिकोण 1 का उपयोग करना संभव है।

एक उदाहरण जो आपके उपयोग के मामले के करीब लगता है (ड्राइंग लाइन, थोड़ा टेक्स्ट और इशारा आंदोलन पर इन अद्यतनों के साथ) MPAndroidChart है। यह एक खुला स्रोत पुस्तकालय है कि उच्च प्रदर्शन (the following comparison यदि आप आँकड़े चाहते हैं)

वर्गों की जांच करने के Renderer वर्गों के रूप में इन चार्ट उपप्रकार के onDraw(Canvas c) में कोड ड्रा होते हैं को प्राप्त होता है। आप वहां उच्च प्रदर्शन प्राप्त करने के लिए उपयोग की जाने वाली कुछ चाल देख सकते हैं:

  1. रेंडर लूप में आवंटित न करें। इसके बजाय, लूप के बाहर आवंटित करें और पुन: उपयोग/रीसायकल चर। LineChartRendererline 199
  2. बफरिंग का उपयोग करें। उदाहरण के लिए, MPAndroidChart में, बार चार्ट में सलाखों के चारों कोनों के लिए अंक बफ़र कर रहे हैं और बफर सरणी पुन: उपयोग किया जाता है। BarBuffer कक्षा देखें।
  3. उपयोग देशी Canvas ड्राइंग कार्य (drawPath, drawLine आदि)

के अनुकूलन प्रतिपादन के लिए सुझावों की एक पूरी सूची एंड्रॉयड प्रदर्शन Slow Rendering Guide

2

दृष्टिकोण 2 में पाया जा सकता सबसे अच्छा एक है। यदि आप झटकेदार लगते हैं, तो इसका मतलब है कि बिटमैप इसे मिटाने के बाद और सभी लाइनों को आकर्षित करने से पहले स्क्रीन पर खींचा जाता है। यदि यह मामला एक और बिटमैप का उपयोग करता है और डबल बफरिंग करता है:

स्क्रीनबिटमैप स्क्रीन स्क्रीन पर खींचा जाता है, ऑफस्क्रीन बिटमैप पृष्ठभूमि में ड्राइंग के लिए उपयोग किया जाता है।

अपनी सभी लाइनें और टेक्स्ट ऑफस्क्रीन बिटमैप पर खींचें, और एक बार समाप्त होने पर, इसे स्क्रीनबिटमैप पर कॉपी करें। ऑनड्रा में, स्क्रीनबिटमैप खींचें।

इन बिटमैप्स बनाएं एक बार (आमतौर पर onSizeChanged में), ताकि OnDraw में कोई alloocation है

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