2010-02-10 4 views
7

Ich spiele mit Android, und ich erstelle eine einfache Twitter App, um zu testen, was ich bisher gelernt habe. Aber ich bin auf ein Problem gestoßen, das ich nicht verstehe. Ich habe einen Thread erstellt, um die Tweets zu holen, keine Probleme, aber ich habe dann einen ProgressDialog hinzugefügt, der angezeigt wurde, wenn dieser Thread ausgeführt wurde. Dies verursachte ein sehr ungewöhnliches Verhalten. Wenn der Benutzer von der vertikalen Ausrichtung zur horizontalen Ausrichtung rotiert, verhält sich das Programm wie erwartet, keine Probleme, aber wenn er sich dann zurückdreht, stürzt das Programm ab und sagt, dass ein Fenster verloren gegangen ist.Android: Absturz bei Rotation, horizontal zu vertikal

Das Problem tritt nur bei einem horizontalen zu vertikalen Layout-Schalter auf. Ich weiß von den Problemen, wenn Sie versuchen, zu rotieren, während das Dialogfeld ausgeführt wird, aber ich habe sichergestellt, dass das Dialogfeld ausgeführt und vor dem Drehen beendet und es weiterhin abstürzt. Heres mein Code:

package com.onesmartpuppy.puppytweet; 
import java.util.ArrayList; 
import com.github.droidfu.widgets.WebImageView; 
import winterwell.jtwitter.Twitter; 
import winterwell.jtwitter.Twitter.Status; 
import android.app.ListActivity; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.View.OnClickListener; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.TextView; 

public class PuppyTweet extends ListActivity implements OnClickListener { 

    private ProgressDialog m_ProgressDialog = null; 
    private ArrayList<Status> messages = null; 
    private TweetAdapter m_adapter; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     messages = new ArrayList<Status>(); 
     this.m_adapter = new TweetAdapter(this, R.layout.row, messages); 
     setListAdapter(this.m_adapter); 

     setupButtons(); 

     m_ProgressDialog = ProgressDialog.show(this,  
      "Please wait...", "Retrieving tweets ...", true); 

     Runnable findTweets = new Runnable(){ 
      @Override 
      public void run() { 

      try { 
       messages = new ArrayList<Status>(); 

       Twitter ourTwitter = new Twitter("*****", "******"); 
       messages = (ArrayList<Status>) ourTwitter.getFriendsTimeline(); 

       Thread.sleep(1000); 
       Log.i("ARRAY", ""+ messages.size()); 
      } catch (Exception e) { 
       Log.e("BACKGROUND_PROC", e.getMessage()); 
      } 
       handler.sendEmptyMessage(0); 
      } 
     }; 

     Thread thread = new Thread(null, findTweets, "FindTweets"); 
     thread.start(); 
    } 



    private void setupButtons() 
    { 
    Button refreshButton = (Button) findViewById(R.id.refresh_button); 
    refreshButton.setOnClickListener(this); 
    Button settingsButton = (Button) findViewById(R.id.settings_button); 
    settingsButton.setOnClickListener(this); 
    Button tweetButton = (Button) findViewById(R.id.update_button); 
    tweetButton.setOnClickListener(this); 
    } 



@Override 
public void onClick(View v) { 
    switch (v.getId()) 
    { 
    case R.id.settings_button: 
    break; 
    case R.id.update_button: 
    break; 
    case R.id.refresh_button: 
    break; 
    default: 
    break; 
    } 
} 

private Handler handler = new Handler() { 

     @Override 
     public void handleMessage(Message msg) { 
      if(messages != null && messages.size() > 0){ 
       m_adapter.clear(); 
       m_adapter.notifyDataSetChanged(); 
       for(int i=0;i<messages.size();i++) 
        m_adapter.add(messages.get(i)); 
      } 
      m_ProgressDialog.dismiss(); 
      m_adapter.notifyDataSetChanged(); 
     } 
    }; 


    private class TweetAdapter extends ArrayAdapter<Status> { 

     private ArrayList<Status> items; 

     public TweetAdapter(Context context, int textViewResourceId, ArrayList<Status> items) { 
       super(context, textViewResourceId, items); 
       this.items = items; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
       View v = convertView; 
       if (v == null) { 
        LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
        v = vi.inflate(R.layout.row2, null); 
       } 
       Status o = (Status) items.get(position); 

       if (o != null) { 
       WebImageView img = (WebImageView) v.findViewById(R.id.webimage);     
         TextView tt = (TextView) v.findViewById(R.id.toptext); 
         TextView bt = (TextView) v.findViewById(R.id.bottomtext); 
         if (tt != null) { 
          tt.setText("Name: " + o.user.name);       } 
         if(bt != null){ 
          bt.setText("Status: " + o.getText()); 
         } 
         if (img !=null) { 
         img.setImageUrl(o.getUser().profileImageUrl.toString()); 
          img.loadImage(); 
         } 
       } 
       return v; 
     } 


    } 
} 

here die LogCat von wo es stürzt ab:

02-10 16:01:05.237: INFO/ActivityManager(63): Config changed: { scale=1.0 imsi=310/260 loc=ld_US touch=3 keys=2/1/2 nav=3/1 orien=2 layout=18} 
02-10 16:01:05.344: WARN/UsageStats(63): Something wrong here, didn't expect com.onesmartpuppy.puppytweet to be resumed 
02-10 16:01:05.384: INFO/WindowManager(63): Setting rotation to 0, animFlags=0 
02-10 16:01:05.394: INFO/ActivityManager(63): Config changed: { scale=1.0 imsi=310/260 loc=ld_US touch=3 keys=2/1/2 nav=3/1 orien=1 layout=18} 
02-10 16:01:05.504: WARN/UsageStats(63): Something wrong here, didn't expect com.onesmartpuppy.puppytweet to be resumed 
02-10 16:01:05.704: ERROR/WindowManager(227): Activity com.onesmartpuppy.puppytweet.PuppyTweet has leaked window [email protected] that was originally added here 
02-10 16:01:05.704: ERROR/WindowManager(227): android.view.WindowLeaked: Activity com.onesmartpuppy.puppytweet.PuppyTweet has leaked window [email protected] that was originally added here 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.view.ViewRoot.<init>(ViewRoot.java:227) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.view.Window$LocalWindowManager.addView(Window.java:424) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.app.Dialog.show(Dialog.java:239) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.app.ProgressDialog.show(ProgressDialog.java:107) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.app.ProgressDialog.show(ProgressDialog.java:90) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at com.onesmartpuppy.puppytweet.PuppyTweet.onCreate(PuppyTweet.java:39) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2470) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3573) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.app.ActivityThread.access$2300(ActivityThread.java:119) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1825) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.os.Handler.dispatchMessage(Handler.java:99) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.os.Looper.loop(Looper.java:123) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at android.app.ActivityThread.main(ActivityThread.java:4310) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at java.lang.reflect.Method.invokeNative(Native Method) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at java.lang.reflect.Method.invoke(Method.java:521) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
02-10 16:01:05.704: ERROR/WindowManager(227):  at dalvik.system.NativeStart.main(Native Method) 
02-10 16:01:06.344: INFO/global(227): Default buffer size used in BufferedReader constructor. It would be better to be explicit if an 8k-char buffer is required. 
02-10 16:01:06.624: DEBUG/dalvikvm(227): GC freed 6082 objects/479568 bytes in 77ms 
02-10 16:01:07.374: DEBUG/dalvikvm(227): GC freed 11982 objects/709808 bytes in 83ms 
02-10 16:01:07.394: INFO/global(227): Default buffer size used in BufferedReader constructor. It would be better to be explicit if an 8k-char buffer is required. 
02-10 16:01:07.564: DEBUG/dalvikvm(227): GC freed 95 objects/79880 bytes in 68ms 
02-10 16:01:07.704: DEBUG/dalvikvm(227): GC freed 8 objects/38992 bytes in 65ms 
02-10 16:01:08.174: DEBUG/dalvikvm(63): GC freed 5407 objects/257208 bytes in 174ms 
02-10 16:01:08.194: INFO/ARRAY(227): 20 
02-10 16:01:08.204: DEBUG/AndroidRuntime(227): Shutting down VM 
02-10 16:01:08.204: WARN/dalvikvm(227): threadid=3: thread exiting with uncaught exception (group=0x4001b188) 
02-10 16:01:08.204: ERROR/AndroidRuntime(227): Uncaught handler: thread main exiting due to uncaught exception 
02-10 16:01:08.214: ERROR/AndroidRuntime(227): java.lang.IllegalArgumentException: View not attached to window manager 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:355) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:200) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at android.view.Window$LocalWindowManager.removeView(Window.java:432) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at android.app.Dialog.dismissDialog(Dialog.java:280) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at android.app.Dialog.access$000(Dialog.java:73) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at android.app.Dialog$1.run(Dialog.java:109) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at android.app.Dialog.dismiss(Dialog.java:264) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at com.onesmartpuppy.puppytweet.PuppyTweet$1.handleMessage(PuppyTweet.java:104) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at android.os.Handler.dispatchMessage(Handler.java:99) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at android.os.Looper.loop(Looper.java:123) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at android.app.ActivityThread.main(ActivityThread.java:4310) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at java.lang.reflect.Method.invokeNative(Native Method) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at java.lang.reflect.Method.invoke(Method.java:521) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
02-10 16:01:08.214: ERROR/AndroidRuntime(227):  at dalvik.system.NativeStart.main(Native Method) 
02-10 16:01:08.244: INFO/Process(63): Sending signal. PID: 227 SIG: 3 
02-10 16:01:08.244: INFO/dalvikvm(227): threadid=7: reacting to signal 3 
02-10 16:01:08.274: ERROR/dalvikvm(227): Unable to open stack trace file '/data/anr/traces.txt': Permission denied 
02-10 16:01:08.754: DEBUG/dalvikvm(227): GC freed 5986 objects/372656 bytes in 316ms 
02-10 16:01:09.829: INFO/ARRAY(227): 20 
02-10 16:01:09.955: INFO/Process(227): Sending signal. PID: 227 SIG: 9 
02-10 16:01:09.974: INFO/ActivityManager(63): Process com.onesmartpuppy.puppytweet (pid 227) has died. 
02-10 16:01:10.014: INFO/WindowManager(63): WIN DEATH: Window{43b653e0 com.onesmartpuppy.puppytweet/com.onesmartpuppy.puppytweet.PuppyTweet paused=false} 
02-10 16:01:10.014: INFO/WindowManager(63): WIN DEATH: Window{43c32b48 Please wait... paused=false} 
02-10 16:01:10.164: WARN/UsageStats(63): Unexpected resume of com.android.launcher while already resumed in com.onesmartpuppy.puppytweet 
02-10 16:01:10.314: WARN/InputManagerService(63): Got RemoteException sending setActive(false) notification to pid 227 uid 10023 
+2

Nutzen Sie die * LogCat * -Funktionalität von Android, lassen Sie Debugging-Anweisungen mit der 'Log'-Klasse in Ihrem Code und öffnen Sie das * LogCat * -Perspektiven-Fenster auf Android und veröffentlichen Sie den Stack-Trace. Es zeigt an, in welcher Zeile das Fensterleck aufgetreten ist und vielleicht, wie es repariert werden kann. –

+1

Haben Sie den StackTrace? –

+0

Die Behandlung der onDestroy und onPause Ereignisse, um diesen Thread zu töten, könnte sich lohnen. wahrscheinlich nicht das Problem. –

Antwort

9

Die WindowLeaked Ausnahme im Protokoll geschieht in der Regel, wenn Sie irgendeine Art von Asynchron-Aufgabe haben, die nach der Aktivität Finishing, die begannen, es ist zerstört.

Wenn Sie den Bildschirm drehen, wird die Aktivität neu erstellt. Unter der Android docs sollten Sie alle Instanzstatus in der OnPause-Methode speichern, einschließlich sicherzustellen, dass alle asynchronen Tasks gestoppt sind. Sie können die onCreate-Methode mithilfe des gespeicherten Pakets erneut erstellen.

+2

bekam Ich fügte eine weitere ablsen() in der onPause-Methode für das Dialogfeld, behoben alle Probleme. Vielen Dank! – Kelend

+0

Vielen Dank für das Verständnis dieses Problems und warum die Lösung funktioniert. Dieses Problem besteht schon lange! Jetzt gibt es kein WindowLeak mehr, da ich das benutzerdefinierte alertdialog in PreferenceActivity onPause() ablehne. Dies würde nur passieren, wenn das Telefon rotierte, während das Dialogfeld angezeigt wurde. –