Sono un principiante assoluto in Java e ho creato un semplice snippet Java per Android dove in un Runnable dopo 1,5 secondi cambio lo TextView
da Hello World
a Hola Mundo
. Funziona perfettamente, in pratica un WeakReference
dovrebbe impedire che questa perdita di memoria avvenga correttamente? Ho il dubbio che non ci sia assolutamente perdita di memoria ogni volta che si verifica l'orientamento del dispositivo. Mi piacerebbe controllare questo, ma non riesco a cambiare orientamento nel mio Android emulato.Questo Runnable è sicuro da perdite di memoria?
Questo è il codice:
package com.example.helloworld;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
import android.util.Log;
import java.lang.ref.WeakReference;
public class HelloWorldActivity extends Activity
{
private Handler h = new Handler();
private static TextView txtview;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtview = (TextView) findViewById(R.id.mainview);
h.postDelayed(new WeakRunnable(txtview),1500);
}
private static final class WeakRunnable implements Runnable {
private final WeakReference<TextView> mtextview;
protected WeakRunnable(TextView textview){
mtextview = new WeakReference<TextView>(textview);
}
@Override
public void run() {
TextView textview = mtextview.get();
if (textview != null) {
txtview.setText("Hola Mundo");
textview = null; // No idea if setting to null afterwards is a good idea
}
Log.d("com.example.helloworld", "" + textview);
}
}
}
EDIT
E 'al sicuro da perdite di memoria, ma alcune risposte sono stati anche occupa il blocco thread dell'interfaccia utente. In realtà questo codice esegue il gestore nel thread principale (UI). Per generare un nuovo thread sto un thread manualmente come segue:
package com.example.helloworld;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
import android.util.Log;
import java.lang.ref.WeakReference;
public class HelloWorldActivity extends Activity
{
private static TextView txtview;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtview = (TextView) findViewById(R.id.mainview);
Thread t = new Thread(new WeakRunnable(txtview));
t.start();
}
private static final class WeakRunnable implements Runnable {
private final WeakReference<TextView> mtextview;
protected WeakRunnable(TextView textview){
mtextview = new WeakReference<TextView>(textview);
}
@Override
public void run() {
TextView textview = mtextview.get();
if (textview != null) {
/*
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
*/
txtview.setText("Hola Mundo");
textview = null;
}
Log.d("com.example.helloworld", "" + Thread.currentThread().getName()); // Outputs "Thread-<num>" if not running on UI thread
}
}
}
Il problema ora è che io non riesco a ritardare la discussione deposto le uova in qualsiasi modo, in caso contrario funziona.
questo:
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
rende l'applicazione stessa chiudere e io non capisco perché. Qualcosa mi dice che lo sto ritardando nel modo sbagliato.
EDIT2
Grazie al collegamento @EugenMatynov mi danno: update ui from another thread in android ho capito perché l'applicazione lasciò. Tutto si riduce al motivo Non è possibile chiamare i metodi dell'interfaccia utente da thread diversi dal thread principale. ed è una cattiva pratica aggiornare l'interfaccia utente da un altro thread.
pulito il gestore del fare la fila su onPause, e sei privo di perdite al 100%. In questo caso. – Blackbelt
Non c'è una perdita di memoria in virtù del campo statico TextView? – stevehs17