2011-03-03 11 views
11

यह समस्या मुझे पागल बनाती है। मुझे गतिविधि के भीतर बनाए गए नए धागे में लंबे संचालन को संभालने और पाठ जैसे दृश्य घटकों को संशोधित करने और लंबे ऑपरेशन के बाद इस तरह के कुछ बुनियादी सिद्धांतों को याद करने के बारे में कुछ बुनियादी लेकिन बहुत महत्वपूर्ण ज्ञान याद आती है।गतिविधि ने खिड़की को लीक किया है [email protected] जो मूल रूप से यहां जोड़ा गया था

mProgressDialog = ProgressDialog.show(mContext, "Tripplanner", "please wait...", true, false); 
connectAndGetRoute(); 


private void connectAndGetRoute(){ 

    new Thread(){ 
     @Override 
     public void run() { 
      try { 
      if(!connectTo9292ov()) return;// conncetto9292ov() connects to a website, parses the reasult into an arraylist. The arraylist contains route. 

      } catch(UnknownHostException e){ 
       Toast.makeText(mContext, "failed to connect to server", Toast.LENGTH_LONG).show(); 
      }catch (ClientProtocolException e) { 
       Toast.makeText(mContext, "failed to connect to server", Toast.LENGTH_LONG).show();     
     } catch (IOException e) { 
       Toast.makeText(mContext, "failed to connect to server", Toast.LENGTH_LONG).show(); 
      } 

      handler.post(runConnection); 
     } 

    }.start(); 

    handler = new Handler(); 
    runConnection = new Runnable(){ 
     @Override 
     public void run() { 
      mProgressDialog.dismiss(); 
      showOnScreen(); 
     } 
    }; 
} 

और इस त्रुटि मैं मिलता है:

ERROR/WindowManager(8297): Activity mp.tripplanner.OvPlanner has leaked window [email protected] that was originally added here 
ERROR/WindowManager(8297): android.view.WindowLeaked: Activity mp.tripplanner.OvPlanner has leaked window [email protected] that was originally added here 
ERROR/WindowManager(8297): at android.view.ViewRoot.<init>(ViewRoot.java:251) 
ERROR/WindowManager(8297): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148) 
ERROR/WindowManager(8297): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 
ERROR/WindowManager(8297): at android.view.Window$LocalWindowManager.addView(Window.java:424) 
ERROR/WindowManager(8297): at android.app.Dialog.show(Dialog.java:241) 
ERROR/WindowManager(8297): at android.app.ProgressDialog.show(ProgressDialog.java:107) 
ERROR/WindowManager(8297): at android.app.ProgressDialog.show(ProgressDialog.java:95) 
ERROR/WindowManager(8297): at mp.tripplanner.OvPlanner$3.onClick(OvPlanner.java:351) 
ERROR/WindowManager(8297): at android.view.View.performClick(View.java:2408) 
ERROR/WindowManager(8297): at android.view.View$PerformClick.run(View.java:8817) 
ERROR/WindowManager(8297): at android.os.Handler.handleCallback(Handler.java:587) 
ERROR/WindowManager(8297): at android.os.Handler.dispatchMessage(Handler.java:92) 
ERROR/WindowManager(8297): at android.os.Looper.loop(Looper.java:144) 
ERROR/WindowManager(8297): at android.app.ActivityThread.main(ActivityThread.java:4937) 
ERROR/WindowManager(8297): at java.lang.reflect.Method.invokeNative(Native Method) 
ERROR/WindowManager(8297): at java.lang.reflect.Method.invoke(Method.java:521) 
ERROR/WindowManager(8297): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
ERROR/WindowManager(8297): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
ERROR/WindowManager(8297): at dalvik.system.NativeStart.main(Native Method) 

लेकिन एक त्रुटि संदेश लॉग में लिखा है

मुझे पहले तुम मेरे कोड का हिस्सा दिखाने जहां इस समस्या होता है उपरोक्त से पहले, जो है:

ERROR/AndroidRuntime(8297): FATAL EXCEPTION: Thread-9 
ERROR/AndroidRuntime(8297): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
ERROR/AndroidRuntime(8297): at android.os.Handler.<init>(Handler.java:121) 
ERROR/AndroidRuntime(8297): at android.widget.Toast.<init>(Toast.java:68) 
ERROR/AndroidRuntime(8297): at android.widget.Toast.makeText(Toast.java:231) 
ERROR/AndroidRuntime(8297): at mp.tripplanner.OvPlanner$4.run(OvPlanner.java:371) 

आपकी मदद के लिए धन्यवाद।

उत्तर

4

यूआई अपडेट करने में सक्षम होने के लिए आपके Handler को आपके यूआई थ्रेड में बनाया जाना चाहिए। मैं तो बल्कि एक runnable पोस्टिंग से हैंडलर के sendMessage विधि का प्रयोग करेंगे,:

private static final int HANDLER_MESSAGE_ERROR = 0; 
private static final int HANDLER_MESSAGE_COMPLETED = 1; 
... 
private void connectAndGetRoute(){ 
    new Thread(){ 
     @Override 
     public void run() { 
      try { 
       if(!connectTo9292ov()) return; 

      } catch(UnknownHostException e){ 
       sendMessage(HANDLER_MESSAGE_ERROR); 
      } catch (ClientProtocolException e) { 
       sendMessage(HANDLER_MESSAGE_ERROR); 
      } catch (IOException e) { 
       sendMessage(HANDLER_MESSAGE_ERROR); 
      } finally { 
       sendMessage(HANDLER_MESSAGE_COMPLETED); 
      } 
     } 
     private void sendMessage(int what){ 
      Message msg = Message.obtain(); 
      msg.what = what; 
      mHandler.sendMessage(msg); 
     } 
    }.start(); 

} 
... 
private Handler mHandler = new Handler(){ 
    @Override 
    public void handleMessage(Message msg) { 
     switch(msg.what){ 
     case HANDLER_MESSAGE_ERROR: 
      Toast.makeText(mContext, "failed to connect to server", Toast.LENGTH_LONG).show(); 
      break; 
     case HANDLER_MESSAGE_COMPLETED: 
      mProgressDialog.dismiss(); 
      showOnScreen(); 
      break; 
     default: 
      Log.w("MyTag","Warning: message type \""+msg.what+"\" not supported"); 
     } 
    } 
} 
+1

बहुत थक गया, इसने समस्या हल की। मैं सिर्फ यह जानना चाहता था कि आप एक रननेबल पोस्ट करने के बजाय हैंडलर के प्रेषण संदेश का उपयोग करने की सलाह देते हैं? – mnish

+1

@ मिशनी अच्छी तरह से दोनों विधियों को काम करना चाहिए, मुझे लगता है कि यदि वे सभी एक ही स्थान पर हैं तो अपने यूआई अपडेट का ट्रैक रखना आसान है। 'SendMessage' का उपयोग करके ज़िम्मेदारी को अलग करना आसान है, इसलिए मुझे डीबग करना आसान लगता है। –

+0

स्पष्ट धन्यवाद! – mnish

1

बस एक त्वरित विचार।

मुझे लगता है, यह धागा के भीतर आपका टोस्ट-संदेश है। उन्हें टिप्पणी करने का प्रयास करें।

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

mProgressDialog = ProgressDialog.show(mContext, "Tripplanner", "please wait...", true, false); 
connectAndGetRoute(); 


private void connectAndGetRoute(){ 

    new Thread(){ 
     @Override 
     public void run() { 
      try { 
      if(!connectTo9292ov()) return;// conncetto9292ov() connects to a website, parses the reasult into an arraylist. The arraylist contains route. 

      } catch(UnknownHostException e){ 
       // an int member of your activity 
       threadStatus = 404; 
       // Toast.makeText(mContext, "failed to connect to server", Toast.LENGTH_LONG).show(); 
      }catch (ClientProtocolException e) { 
       threadStatus = 404; 
       // Toast.makeText(mContext, "failed to connect to server", Toast.LENGTH_LONG).show();     
     } catch (IOException e) { 
       threadStatus = 404; 
       // Toast.makeText(mContext, "failed to connect to server", Toast.LENGTH_LONG).show(); 
      } 
      finally { 
      handler.post(runConnection);} 
     } 

    }.start(); 

    handler = new Handler(); 
    runConnection = new Runnable(){ 
     @Override 
     public void run() { 
      if (threadStatus == 404) { Toast.makeText(mContext, "failed to connect to server", Toast.LENGTH_LONG).show();} 
      else { 
      mProgressDialog.dismiss(); 
      showOnScreen();} 
     } 
    }; 
} 
+0

आप सही अनुमान लगाया है, और यह भी अनुमान लगाया लेकिन यकीन नहीं था, और अभी भी कैसे solveit को पता नहीं है। क्योंकि मुझे आपके द्वारा पेश किए गए समाधान को समझ में नहीं आता है: डी। क्या आप कृपया मुझे बता सकते हैं कि धागे की स्थिति को सहेजकर आप क्या मतलब रखते हैं और मैं यह कैसे कर सकता हूं? मुझे वास्तव में आपके समाधान पर अधिक स्पष्टीकरण की आवश्यकता है: डी। माफ़ कीजिये। – mnish

+1

मैंने आपके कोड को थोड़ा सा संशोधित किया। यदि आप मुझे कारण के लिए पूछते हैं, तो आपको धागे से अपने यूई को अपडेट करने की अनुमति नहीं है। आपको इसे बाहर करना चाहिए। – Tima

+0

और @ ओल्स्लाव के उत्तर – Tima

1

नमूना कोड ब्लॉक से:

new Thread(new Runnable() {     
       @Override 
       public void run() { 
        doNotUIthings(); 
        updateUI.sendEmptyMessage(0); //Update ui in UI thread 
       } 
       private Handler updateUI = new Handler(){ 
        @Override 
        public void dispatchMessage(Message msg) { 
         super.dispatchMessage(msg); 
         updateUI(); 
        } 
       }; 
      }).start(); 

लेकिन मैं जावा धागे के बजाय AsyncTask उपयोग करने के लिए सलाह देते हैं।

+0

बहुत धन्यवाद। वास्तव में इसके बावजूद कभी नहीं। हालांकि मुझे नहीं पता कि यह कैसे काम करता है लेकिन मैं निश्चित रूप से भविष्य में इसका उपयोग करने पर विचार करूँगा यदि वर्तमान समस्या फिर से होती है। लेकिन अभी के लिए मैं डेव सी द्वारा पेश किए गए समाधान के साथ आगे बढ़ूंगा क्योंकि यह मेरे लिए ठीक काम करता है। – mnish

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