我在Java中的总的初学者和已经创建了一个简单的Java的Android片断其中一个Runnable 1,5秒钟后,我改变TextView从Hello
World到Hola
Mundo。它工作正常,基本上WeakReference应该防止这种内存泄漏发生吗?我怀疑在发生设备定向时是否绝对没有内存泄漏。我很乐意对此进行检查,但无法在模拟的Android中更改方向。
这是代码:
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 mtextview;
protected WeakRunnable(TextView textview){
mtextview = new WeakReference(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);
}
}
}
编辑
它可以防止内存泄漏,但也有一些答案与UI线程阻塞有关。实际上,此代码在主(UI)线程中运行处理程序。要产生一个新线程,我要手动产生一个线程,如下所示:
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 mtextview;
protected WeakRunnable(TextView textview){
mtextview = new WeakReference(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-" if not running on UI thread
}
}
}
现在的问题是,我似乎无法以任何方式延迟生成的线程,否则它将起作用。
这个:
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
使应用本身退出,我不明白为什么。某事告诉我,我以错误的方式延迟了它。
编辑2
感谢@EugenMatynov给我的链接:从android中的另一个线程更新ui,我理解了为什么退出该应用程序。归结为 您不能从主线程以外的线程调用UI方法 的原因
。 并且从另一个线程更新UI是一种不好的做法。