2013-10-28 5 views
11

में ऑन ड्रा() विधि में बिटमैप को तेजी से कैसे आकर्षित करें I एंड्रॉइड में एकल टैप विधि पर मार्कर आकर्षित करने का प्रयास कर रहा हूं। जब मैं मार्कर खींचता हूं तो यह आकर्षित होगा लेकिन 30-40 मिलीसेकंड को खींचने में अधिक समय लगेगा, इसमें 2-3 सेकंड लगते हैं। यहां कक्षा के लिए मेरा कोड है जिसमें मेरे पास विधि है।कैनवास एंड्रॉइड

public class MyItemizedOverlay extends ItemizedOverlay<OverlayItem> { 

    private ArrayList<OverlayItem> overlayItemList = new ArrayList<OverlayItem>(); 

    public MyItemizedOverlay(Drawable pDefaultMarker, 
      ResourceProxy pResourceProxy) { 
     super(pDefaultMarker, pResourceProxy); 
    } 

    @Override 
    public void draw(Canvas canvas, MapView mapView, boolean arg2) { 
     super.draw(canvas, mapView, arg2); 

     // ---translate the GeoPoint to screen pixels--- 
     Point screenPts = new Point(); 
     mapView.getProjection().toPixels(p, screenPts); 

     // ---add the marker--- 
     Bitmap bmp = BitmapFactory.decodeResource(getResources(), 
       R.drawable.pin_annotation_darkblue); 
     Bitmap bmp1 = BitmapFactory.decodeResource(getResources(), 
       R.drawable.pin_annotation_green); 
     Bitmap bmp2 = BitmapFactory.decodeResource(getResources(), 
       R.drawable.pin_annotation_bue); 
     Bitmap bmp3 = BitmapFactory.decodeResource(getResources(), 
       R.drawable.pin_annotation_light); 
     Bitmap bmp4 = BitmapFactory.decodeResource(getResources(), 
       R.drawable.pin_annotation_light); 
     Bitmap bmp5 = BitmapFactory.decodeResource(getResources(), 
       R.drawable.pin_annotation_light); 
     Bitmap bmp6 = BitmapFactory.decodeResource(getResources(), 
       R.drawable.pin_annotation_light); 
     if (count == 1) { 
      int caller = getIntent().getIntExtra("button", 0); 
      switch (caller) { 
      case R.id.btMap: 
       canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null); 
       bmp.recycle(); 
       break; 
      case R.id.imageButton1: 
       canvas.drawBitmap(bmp1, screenPts.x, screenPts.y - 50, null); 
       bmp1.recycle(); 
       break; 
      case R.id.imageButton2: 
       canvas.drawBitmap(bmp2, screenPts.x, screenPts.y - 50, null); 
       bmp2.recycle(); 
       break; 
      case R.id.imageButton3: 
       canvas.drawBitmap(bmp3, screenPts.x, screenPts.y - 50, null); 
       bmp3.recycle(); 
       break; 
      case R.id.imageButton4: 
       canvas.drawBitmap(bmp4, screenPts.x, screenPts.y - 50, null); 
       bmp4.recycle(); 
       break; 
      case R.id.imageButton5: 
       canvas.drawBitmap(bmp5, screenPts.x, screenPts.y - 50, null); 
       bmp5.recycle(); 
       break; 
      case R.id.imageButton6: 
       canvas.drawBitmap(bmp6, screenPts.x, screenPts.y - 50, null); 
       bmp6.recycle(); 
       break; 
      } 
     } 
     // Bitmap bmp = BitmapFactory.decodeResource(getResources(), 
     // R.drawable.pin_annotation_green); 
     // if (count == 1) { 
     // canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null); 
     // } 
} 

उत्तर

18

आपको कन्स्ट्रक्टर में सभी बिटमैप्स प्रारंभ करना चाहिए। डीकोडिंग बिटमैप में काफी समय लगता है। आप उन्हें स्टोर करने के लिए HashMap (कुंजी, मान) का उपयोग कर सकते हैं। फिर ऑन ड्रा में, मिलान किए गए बिटमैप प्राप्त करें और इसे सीधे खींचें।

उदाहरण

public class MyView extends View{ 

    private HashMap<String, Bitmap> mStore = new HashMap<String, Bitmap>(); 
    public MyView(Context context) { 
     super(context); 
     // TODO Auto-generated constructor stub 

     init(); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     // TODO Auto-generated method stub 

     int caller = getIntent().getIntExtra("button", 0); 
     Bitmap bmp = null; 
     switch (caller) { 
     case R.id.btMap: 
      bmp = mStore.get(R.id.btMap); 
      canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null); 
      bmp.recycle(); 
      bmp = null; 
      break; 
     case R.id.imageButton1: 
      bmp = mStore.get(R.id.imageButton1); 
      canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null); 
      bmp1.recycle(); 
      bmp1 = null; 
      break; 
     } 

     super.onDraw(canvas); 
    } 

    public void init() { 
     Bitmap bmp = BitmapFactory.decodeResource(getResources(), 
       R.drawable.pin_annotation_darkblue); 
     mStore.put(R.id.btMap, bmp); 

     bmp = BitmapFactory.decodeResource(getResources(), 
       R.drawable.pin_annotation_green); 
     mStore.put(R.id.imageButton1, bmp); 
    } 
} 

यहाँ के लिए मैं अपने कोड के आधार पर क्या किया है है। आपको कुछ डुप्लीकेट संसाधन आईडी जांचनी होंगी।

private ArrayList<OverlayItem> overlayItemList = new ArrayList<OverlayItem>(); 
private HashMap<String, Bitmap> mStore = new HashMap<String, Bitmap>(); 

public MyItemizedOverlay(Drawable pDefaultMarker, 
     ResourceProxy pResourceProxy) { 
    super(pDefaultMarker, pResourceProxy); 

    Bitmap bmp = BitmapFactory.decodeResource(getResources(), 
      R.drawable.pin_annotation_darkblue); 
    mStore.put(R.id.btMap, bmp); 
    bmp = BitmapFactory.decodeResource(getResources(), 
      R.drawable.pin_annotation_green); 
    mStore.put(R.id.imageButton1, bmp); 
    bmp = BitmapFactory.decodeResource(getResources(), 
      R.drawable.pin_annotation_bue); 
    mStore.put(R.id.imageButton2, bmp); 
    bmp = BitmapFactory.decodeResource(getResources(), 
      R.drawable.pin_annotation_light); 
    mStore.put(R.id.imageButton3, bmp); 
    bmp = BitmapFactory.decodeResource(getResources(), 
      R.drawable.pin_annotation_light); // check it 
    mStore.put(R.id.imageButton4, bmp); 
    bmp = BitmapFactory.decodeResource(getResources(), 
      R.drawable.pin_annotation_light); // check it 
    mStore.put(R.id.imageButton5, bmp); 
    bmp = BitmapFactory.decodeResource(getResources(), 
      R.drawable.pin_annotation_light); // check it 
    mStore.put(R.id.imageButton6, bmp); 

} 

@Override 
public void draw(Canvas canvas, MapView mapView, boolean arg2) { 
    super.draw(canvas, mapView, arg2); 

    // ---translate the GeoPoint to screen pixels--- 
    Point screenPts = new Point(); 
    mapView.getProjection().toPixels(p, screenPts); 

    // ---add the marker--- 
    if (count == 1) { 
     int caller = getIntent().getIntExtra("button", 0); 
     Bitmap bmp = null; 

     switch (caller) { 
     case R.id.btMap: 
      bmp = mStore.get(R.id.btMap); 
      canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null); 
      bmp.recycle(); 
      break; 
     case R.id.imageButton1: 
      bmp = mStore.get(R.id.imageButton1); 
      canvas.drawBitmap(bmp1, screenPts.x, screenPts.y - 50, null); 
      bmp.recycle(); 
      break; 
     case R.id.imageButton2: 
      bmp = mStore.get(R.id.imageButton2); 
      canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null); 
      bmp.recycle(); 
      break; 
     case R.id.imageButton3: 
      bmp = mStore.get(R.id.imageButton3); 
      canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null); 
      bmp.recycle(); 
      break; 
     case R.id.imageButton4: 
      bmp = mStore.get(R.id.imageButton4); 
      canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null); 
      bmp.recycle(); 
      break; 
     case R.id.imageButton5: 
      bmp = mStore.get(R.id.imageButton5); 
      canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null); 
      bmp.recycle(); 
      break; 
     case R.id.imageButton6: 
      bmp = mStore.get(R.id.imageButton6); 
      canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null); 
      bmp.recycle(); 
      break; 
     } 
    } 
    // Bitmap bmp = BitmapFactory.decodeResource(getResources(), 
    // R.drawable.pin_annotation_green); 
    // if (count == 1) { 
    // canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null); 
    // } 
} 
+0

हमें [बातचीत में इस चर्चा को जारी रखें] (http://chat.stackoverflow.com/rooms/40102/discussion-between-gaurav- कुमार-and-yushulx) –

+0

कोड साझा करने के लिए धन्यवाद। लेकिन मुझे नहीं लगता कि आपको पहले उदाहरण में स्विच की जरूरत है। बस यह करें: 'int caller = getIntent()। GetIntExtra ("बटन", 0); बिटमैप बीएमपी = mStore.get (कॉलर); canvas.drawBitmap (बीएमपी, screenPts.x, screenPts.y - 50, शून्य); bmp.recycle(); बीएमपी = शून्य; ब्रेक; } ' –

2

आप अपने draw() विधि से सभी BitmapFactory.decodeResource() कॉल निकाल देना चाहिए। केवल एक बार बिटमैप डीकोड करें और इसके संदर्भ में रखें। फिर बस अपने draw() विधि में canvas.drawBitmap() पर कॉल करें।

7

अपने कोड को अनुकूलित करने का विचार केवल ड्राइंग के लिए आवश्यक संचालन करना है। तो आपको, अपनी ऑन ड्रा विधि से हटा देना चाहिए:

  • कोई भी प्रतिशोध: वे लंबे समय तक लेते हैं, ड्रा को अक्सर बुलाया जाता है और आप इतनी नई वस्तुओं को नहीं बनाना चाहते हैं। ऑनआउट के दौरान स्क्रीनपेट स्टोर करें और हमेशा एक ही बिंदु का पुन: उपयोग करें।
  • बिटमैपफैक्टरी.decodeResource: इसमें काफी लंबा समय लगता है। पहले अपना बिटकमैप डीकोड करें, उन्हें स्टोर करें और केवल उन्हें ड्रा के दौरान खींचें।
  • बिटमैप्स रीसायकल करते हैं जब आपको उनकी आवश्यकता नहीं होती है, हर बार जब आप उन्हें आकर्षित नहीं करते हैं।

उदाहरण के लिए:

  • onResume के दौरान अपने बिटमैप्स डिकोड
  • onPause के दौरान उन्हें रीसायकल
  • डिकोडिंग एक async कार्य के अंदर होने चाहिए। जब एसिंक कार्य खत्म हो जाता है, तो इंगित करने के लिए ध्वज उठाएं कि छवियां तैयार हैं और खींची जा सकती हैं।
  • पृष्ठभूमि में छवियों को डीकोड करना बहुत महत्वपूर्ण है क्योंकि इसमें काफी समय लगता है। मुख्य यूआई थ्रेड में ऐसा मत करो। अन्यथा आपका ऐप उत्तरदायी नहीं होगा
  • अपनी स्क्रीन की गणना करें और अंदर के समान बिंदुओं का पुन: उपयोग करें।
  • या तो ड्रॉइन्टेंट को कॉल करने के दौरान कॉल न करें।

संक्षेप में, ड्रॉ के दौरान संचालन को कम करें और आप लगभग 60 एफपीएस के लिए तेजी से ड्राइंग प्राप्त करेंगे।

आपको उस (बदसूरत) स्विच को हटाने और गिनती के मूल्यों को जोड़ने और बिटमैप को आकर्षित करने के लिए हैशैप का उपयोग करना चाहिए। एक सरणी भी तेज हो सकती है और शायद यहां अधिक उपयुक्त हो सकती है।

+0

क्या आप मुझे कुछ कोड दे सकते हैं। क्योंकि मैं इसे और अधिक नहीं रोकता हूं। –

+4

@ गौराव कुमार मुझे लगता है कि उपर्युक्त उत्तर पूरा हो गया है और नहीं लगता कि किसी भी कोड की आवश्यकता है। सबसे पहले आप गतिविधि जीवन चक्र को समझने की कोशिश करते हैं तो आप उपर्युक्त चीजों को आसानी से लागू कर सकते हैं।आपको समझना चाहिए कि कितनी बार और किस विधि को बुलाया जाएगा। फिर यूआई थ्रेड से भारी कोड निकालने के लिए अपने कोड का पुन: उपयोग करने का प्रयास करें और हमेशा थ्रेड या एसिंक कार्यों (एंड्रॉइड में अनुशंसित) का उपयोग करें और आप कर चुके हैं। "स्निकोलस" द्वारा दी गई अवधारणा बहुत सामान्य है और सभी प्लेटफार्मों पर लागू की जा सकती है। –

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