
[英]Should I worry about memory leaks and using WeakReference with Volley in Android
[英]How can I resolve warnings about memory leaks when using android Handler?
我是學習android的初學者。 我在學習 Thread 時使用了 Handler。 順便說一句,我在 android studio 中使用 Handler 警告 memory 泄漏。 我搜索了很多不同的問題,但沒有與我的案例相對應的部分。 使用處理程序時,如何解決有關 memory 泄漏的警告?
public class HandlerActivity extends AppCompatActivity implements Runnable {
ProgressBar pb;
TextView txtRate;
Button btnStart;
static int value;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progress);
pb = findViewById(R.id.pb);
txtRate = findViewById(R.id.txtRate);
btnStart = findViewById(R.id.btnStart);
btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Thread th = new Thread(HandlerActivity.this);
th.start();
}
});
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
pb.setProgress(value);
txtRate.setText("Process : " + value + "%");
}
};
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
value = i;
handler.sendEmptyMessage(0);
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(HandlerActivity.this, "Progress Done !", Toast.LENGTH_SHORT).show();
}
});
}
}
基本上TextView
或任何其他View
持有代表相應Activity
的Context
object 的引用。 當您在Thread
中保留對任何View
的強引用時,您不僅存儲了View
object,而且還存儲了一個Context
object 代表創建它的Activity
。 現在由於Thread
不與 Activity 生命周期綁定,即使在Activity
被銷毀后它們也會繼續運行。 如果是這種情況, Thread
將通過該View
object 保存已破壞的Activity
引用,從而創建 memory 泄漏。
上述問題可以通過存儲View
object 的弱引用來解決,以便 GC 可以在必要時對其進行垃圾回收。 通過以下方式,您可以擺脫 memory 泄漏:
public class HandlerActivity extends AppCompatActivity implements Runnable {
WeakReference<ProgressBar> pb;
WeakReference<TextView> txtRate;
Button btnStart;
static int value;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
pb = new WeakReference<>(findViewById(R.id.pb)); // you may require to cast findViewById() to ProgressBar
txtRate = new WeakReference<>(findViewById(R.id.txtRate)); // you may require to cast findViewById() to TextView
...
}
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(pb.get()!=null) pb.get().setProgress(value);
if(txtRate.get()!=null) txtRate.get().setText("Process : " + value + "%");
}
};
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
// Its always recommended to check if activity is running and stop the thread if not running
if(isFinishing() || isDestroyed()) {
return;
}
}
}
}
Roaim, Mark Keen 在他們的幫助下,我解決了這個問題並自己給出了完整的答案。 感謝 Roaim,Mark Keen。
public class HandlerActivity extends AppCompatActivity implements Runnable {
ProgressBar pb;
TextView txtRate;
Button btnStart;
int value;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progress);
pb = findViewById(R.id.pb);
txtRate = findViewById(R.id.txtRate);
btnStart = findViewById(R.id.btnStart);
btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Thread th = new Thread(HandlerActivity.this);
th.start();
}
});
}
private static class WeakHandler extends Handler {
private final WeakReference<HandlerActivity> mWeakActivity;
private WeakHandler(HandlerActivity AppCompatActivity) {
mWeakActivity = new WeakReference<>(AppCompatActivity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
HandlerActivity _activity = mWeakActivity.get();
if (_activity != null) {
switch (msg.what) {
case 0:
_activity.pb.setProgress(_activity.value);
_activity.txtRate.setText("Process : " + _activity.value + "%");
break;
}
}
}
}
private final WeakHandler mHandler = new WeakHandler(this);
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
value = i;
mHandler.sendEmptyMessage(0);
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(HandlerActivity.this, "Progress Done !.", Toast.LENGTH_SHORT).show();
}
});
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.