2016-07-31 21 views
0

Ich habe 15 Stunden lang versucht, mein Speicherproblem zu beheben, dann lesen Sie einige Fragen dazu, aber ich finde nicht wirklich eine gute Antwort und Lösung.Handler Speicherlecks

Ich sende zwei Integer jedes Mal, wenn die MediaPlayer-Zeit von setOnBufferingUpdateListener mit einem Handler aktualisiert wird. Setzen Sie dann die Ganzzahlen auf zwei TextViews. Aber jedes Mal aktualisiert sich die Zeit. Der Android-Monitor des Android Studios zeigt mir, dass der Speicher um ein Megabyte inkrementiert wird.

Ich will das nicht. Hier meine Klassen.

Der Handler:

public class UpdateH extends android.os.Handler { 

private OnUpdate onUpdate; 

public UpdateH() { 
} 

public UpdateH(Callback callback) { 
    super(callback); 
} 

public UpdateH(Looper looper) { 
    super(looper); 
} 

public UpdateH(Looper looper, Callback callback) { 
    super(looper, callback); 
} 

@Override 
public void handleMessage(Message msg) { 
    onUpdate.update(msg.arg1, msg.arg2); 
} 

public void setOnUpdate(OnUpdate onUpdate) { 
    this.onUpdate = onUpdate; 
} 

public interface OnUpdate{ 
    void update(int cu, int t); 
} 

}

im Fragmente:

@Override 
public void onPause() { 
    super.onPause(); 
    Player.playerProgressHandler = null; 
    mu = null; 
} 

private UpdateH mu; 

@Override 
public void onResume() { 
    super.onResume(); 
    mu = new UpdateH(Looper.getMainLooper()); 

    mu.setOnUpdate(new UpdateH.OnUpdate() { 
     @Override 
     public void update(int cu, int t) { 
      setTime(cu, t); 
     } 
    }); 
    Player.playerProgressHandler = mu; 
} 

private void setTime(int current, int total){ 
    this.current.setText(String.format("%02d:%02d:%02d", 
      (int) ((current/(1000 * 60 * 60)) % 24), 
      (int) ((current/(1000 * 60)) % 60), 
      (int) (current/1000) % 60)); 

    this.total.setText(String.format("%02d:%02d:%02d", 
      (int) ((total/(1000 * 60 * 60)) % 24), 
      (int) ((total/(1000 * 60)) % 60), 
      (int) (total/1000) % 60)); 
} 

im Gewinde:

if(playerProgressHandler != null && mp != null && mp.isPlaying()){ 
        Message message = Message.obtain(); 
        message.setTarget(playerProgressHandler); 
        message.arg1 = mp.getCurrentPosition(); 
        message.arg2 = mp.getDuration(); 
        message.sendToTarget(); 
       } 

Das Problem kommt von der setTime Methode. Denn wenn ich die Codes darin kommentiere. Die Erinnerung bleibt cool.

Hinweis: AsyncTask kann es nicht beheben, denken, wenn über AsyncTask

Antwort

-1

Wenn Sie einen Thread ausführen, können Sie es in Ihrem onDestroy stornieren müssen (oder möglicherweise onPause oder OnStop, wenn es nicht benötigt ausgeführt werden, wenn Sie nicht auf dem Bildschirm sind), so dass es beendet wird und Müll gesammelt werden kann. Sobald der Thread als Garbage Collection erfasst wurde, sind keine Referenzen mehr in den Textansichten vorhanden, sodass der Rest der Aktivität als Garbage Collected erfasst werden kann. Stellen Sie sicher, dass das Runnable beendet wird. Dies bedeutet, dass überprüft werden muss, ob der Thread in seiner Hauptschleife abgebrochen wurde.

Wenn Sie in einer selbstreferenziellen Schleife an Handler schreiben, müssen Sie alle Nachrichten vom Handler an derselben Stelle löschen.

Und nur ein FYI - Ihr gesamter Updater ist viel komplexer als es sein muss.

+0

Wie gesagt, das Problem ist nicht über den Thread. Die Ganzzahlen werden vom Callback des MediaPlayer.setOnBufferingUpdateListener gesendet. Es geht um die settext-Methode für die TextView. – user3502626

+0

Sie irren sich - es geht um den Thread. Der Thread wird fortgesetzt, nachdem die Aktivität zerstört wurde, hat jedoch einen Verweis auf die Aktivität aufgrund des Aufrufs zum Festlegen der Textansicht. Dies führt dazu, dass die gesamte Aktivität und alle zugehörigen Sichten und Variablen verloren gehen. Fix den Faden und das Leck geht. –

+0

Aber ich kann den Thread nicht reparieren, weil ich die [MediaPlayer-Klasse] (https://developer.android.com/reference/android/media/MediaPlayer.html) verwende. Meine Codes werden aufgerufen, wenn die MediaPlayer-Zeit vom setOnBufferingUpdateListener aktualisiert wird. ** Ich habe keinen Thread erstellt, um mein TextView zu aktualisieren. Dieser Thread ist von Android und ich kann nichts dagegen tun. Plus, der Code funktioniert gut, denn wenn ich die Aktivität schließe, wird der Speicher nicht erhöht, weil ich den Handler auf Null gesetzt habe, wenn ich Aktivität onPause ** – user3502626

0

I'ts ok jetzt. Ich warte einige Minuten. dann sinkt der Speicher alleine. Es ist nur langsam, die nicht referenzierten Variablen zu löschen.