Ist dieses Runnable vor Speicherverlusten geschützt?
Ich bin ein absoluter Anfänger in Java und habe ein einfaches Java-Android-Snippet erstellt, in dem ich in einem Runnable nach 1,5 Sekunden das @ änderTextView
vonHello World
zuHola Mundo
. Es funktioniert einwandfrei, im Grunde einWeakReference
sollte verhindern, dass dieser Speicherverlust auftritt, oder? Ich habe Zweifel, ob es bei jeder Geräteorientierung überhaupt keinen Speicherverlust gibt. Ich würde das gerne überprüfen, kann aber die Ausrichtung in meinem emulierten Android nicht ändern.
Dies ist der Code:
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);
}
}
}
BEARBEITE
Es ist sicher vor Speicherverlusten, aber einige Antworten betrafen auch das Blockieren von UI-Threads. Tatsächlich führt dieser Code den Handler im Hauptthread (UI) aus. Um einen neuen Thread zu spawnen, spawne ich einen Thread manuell wie folgt:
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
}
}
}
Das Problem ist jetzt, dass ich den gespawnten Thread in keiner Weise verzögern kann, sonst funktioniert es.
Dies
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
lässt die App sich selbst beenden und ich verstehe nicht warum. Irgendwas sagt mir, dass ich es falsch aufschiebe.
EDIT2
Danke an den Link @EugenMatynov gib mir:update ui von einem anderen Thread in Android Ich habe verstanden warum die App beendet wurde. Auf den Grund kommt es anSie können keine UI-Methoden von anderen Threads als dem Haupt-Thread aufrufen. und es ist eine schlechte Praxis, die Benutzeroberfläche von einem anderen Thread zu aktualisieren.