2012-10-06 18 views
5

मैंने अपना पहला लाइव वॉलपेपर एक अलग धागे में ड्राइंग को लागू करने के लिए बनाया है। तो अब मेरे पास एक वॉलपेपर सेवा है और मेरा वॉलपेपरपेन्टर जो नौकरी करता है। समस्या यह है कि मुझे कुछ डिवाइसों पर unlockCanvasAndPost विधि में IllegalArgumentException मिल रहा है (सैमसंग नोट एक है)। मैंने उन सभी सिफारिशों को पढ़ लिया है जो मुझे मिल सकती हैं लेकिन उस बग को ठीक नहीं कर सका। लगता है कि unlockCanvasAndPost कहा जाता है जब सतह नष्ट हो जाती है तो कैनवास अमान्य है।अनलॉक कैनवास एंडपोस्ट (एंड्रॉइड लाइव वॉलपेपर) में अवैध अर्ग्यूमेंट अपवाद

वॉलपेपर सेवा में:

@Override 
    public void onSurfaceChanged(SurfaceHolder holder, int format, int width, 
      int height) { 
     super.onSurfaceChanged(holder, format, width, height); 
     painting.setSurfaceSize(width, height); 
    } 

    @Override 
    public void onSurfaceCreated(SurfaceHolder holder) { 
     super.onSurfaceCreated(holder); 
     painting.start(); 
    } 

    @Override 
    public void onSurfaceDestroyed(SurfaceHolder holder) { 
     boolean retry = true; 
     painting.stopPainting(); 
     while (retry) { 
      try { 
       painting.join(); 
       retry = false; 
      } catch (InterruptedException e) { } 
     } 
     super.onSurfaceDestroyed(holder); 
    } 

चित्रकला धागा में:

public void stopPainting() { 
    this.run = false; 
    synchronized(this) { 
     this.notify(); 
    } 
} 

public void run() { 
    this.run = true; 
    Canvas c = null; 
    while (run) { 
     try { 
      synchronized (this) { 
       Thread.sleep(50); 
       c = this.surfaceHolder.lockCanvas(); 
       doDraw(c); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } finally { 
      if (c != null) { 
       this.surfaceHolder.unlockCanvasAndPost(c); // << -- HERE IS THE PROBLEM 
      } 
     } 
     // if pause... 
     synchronized (this) { 
      if (wait) { 
       try { 
        wait(); 
       } catch (Exception e) { } 
      } 
     } 
    } 
} 

किसी को भी मुझे किसी भी सुराग मैं गलत क्या कर रहा दे सकते हैं यहाँ कोड के आवश्यक हिस्से है? मैं जावा और एंड्रॉइड दोनों के लिए नया हूँ।

उत्तर

1

मुझे एक निश्चित समस्या नहीं दिखाई देती है लेकिन यहां कुछ विचार हैं।

  • एक मौका है कि आप एक कैनवास अनलॉक करते हैं जिसे लॉक नहीं किया गया है। मैं आपके while लूप के शीर्ष पर c = null; सेट करूंगा अन्यथा c का पिछला मान अगली बार लूप के माध्यम से अनलॉक हो जाएगा।

    while (run) { 
        Canvas c = null; 
        ... 
    
  • आपका run क्षेत्र volatile के रूप में चिह्नित किया जाना चाहिए, क्योंकि यह एक से अधिक थ्रेड द्वारा पहुँचा है।

  • को synchronized ब्लॉक के अंदर कभी भी कॉल न करें। यह एक बहुत बुरा अभ्यास है क्योंकि यह अन्य धागे को अनावश्यक रूप से अवरुद्ध करता है।

  • सुनिश्चित करें कि आप कम से कम अपने अपवाद लॉग इन करें। catch (Exception e) {} के बारे में बेहद सावधान रहें। जो कुछ करता है वह आपकी समस्याओं को मुखौटा करता है।

  • while लूप के अंदर join() करने में बहुत कुछ नहीं है। यदि आपका धागा बाधित हो जाता है तो आपको पेंटिंग थ्रेड को बाधित करना चाहिए और छोड़ देना चाहिए।

  • जब से तुम दोनों सो रहे हैं और प्रतीक्षा, इसे और अधिक समझ बनाने हैं नींद को हटाने और की तरह कुछ करने के लिए:

    try { 
        synchronized (this) { 
         if (wait) { 
          wait(); 
         else { 
          wait(50); 
         } 
        } 
    } catch (Exception e) { 
        e.printStackTrace(); 
    } 
    
2

तो त्रुटि है: UnlockAndPost विफल, इसका मतलब है यह कोई बफर अनलॉक नहीं किया। this.surfaceHolder.unlockCanvasAndPost(c);
के बाद आप जोड़ सकते हैं
this.surfaceHolder.lockCanvas();
(मेरे गरीब अंग्रेजी प्रवीणता के लिए खेद है)

2

जब आप वॉलपेपर का पूर्वावलोकन खोलते हैं, तो वस्तु WallpaperService बनाता है और आगे इंजन का एक उदाहरण बनाता है। फिर स्ट्रीम वॉलपेपर ड्राइंग शुरू होता है।

फिर, जब आप "वॉलपेपर सेट करें" पर क्लिक करते हैं - वॉलपेपर सेवा का एक नया उदाहरण नहीं बनाया गया है। लेकिन वह ऑनक्रेटइंजिन() विधि को कॉल करता है, जो इंजन का एक और (दूसरा) उदाहरण देता है।जो भी अपना धागा चलाता है।

अब आपके पास दो प्रतिस्पर्धी धागे हैं !!! तो वे फेंक दिया एक अपवाद का कारण बनता है।

आप सभी बग को ठीक करने करने की जरूरत है - एक सही विधि onCreateEngine() लिखने के लिए है।

इस बदलें:

@Override 
public Engine onCreateEngine() { 
    return new SampleEngine(); 
} 
इस के लिए

:

private SampleEngine engine; 

@Override 
public Engine onCreateEngine() { 

    if (engine!=null) { 
     engine.painting.stopPainting(); 
     engine = null; 
    } 
    engine = new SampleEngine(); 
    return engine; 
} 
1

मैं अपने लाइव वॉलपेपर के साथ एक ही समस्या थी। नेक्सस 5 एमुलेटर पर यह ठीक चलता है, लेकिन जब मैं इसे नेक्सस 10 एमुलेटर पर चलाता हूं तो यह ऐप लोड होने के पल में दुर्घटनाग्रस्त हो जाता है।

मुझे पता चला कि समस्या यह थी क्योंकि एम्यूलेटर के लिए डिफ़ॉल्ट त्वचा में गलत समाधान है। त्वचा को "नो स्किन" में बदलने के बाद मुझे अब दुर्घटना नहीं मिलती है।

कैसे गलत संकल्प के साथ त्वचा को ठीक करने के बारे में अधिक जानकारी के लिए, कृपया देखें: Android Studio - Tablet emulator not showing correct resolution

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