Tôi là một người mới bắt đầu với Java và đã tạo ra một đoạn mã Java đơn giản, trong đó trong Runnable sau 1,5 giây, tôi thay đổi TextView
từ Hello World
thành Hola Mundo
. Nó hoạt động hoàn hảo, về cơ bản một WeakReference
nên ngăn chặn rò rỉ bộ nhớ này xảy ra đúng không? Tôi có một nghi ngờ nếu có hoàn toàn không có rò rỉ bộ nhớ bất cứ khi nào định hướng thiết bị xảy ra. Tôi rất thích kiểm tra điều này nhưng không thể xoay sở để thay đổi định hướng trong Android mô phỏng của tôi.Đây có phải là Runnable an toàn do rò rỉ bộ nhớ không?
Đây là mã:
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
Đó là an toàn từ rò rỉ bộ nhớ nhưng một vài câu trả lời cũng được quan tâm với thread UI chặn. Trong thực tế, mã này chạy Trình xử lý trong luồng chính (UI). Để đẻ trứng một chủ đề mới Tôi đang đẻ trứng một sợi thủ công như sau:
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
}
}
}
Vấn đề bây giờ là tôi dường như không thể trì hoãn thread sinh ra trong bất kỳ cách nào, nếu không nó hoạt động.
này:
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
làm cho các ứng dụng bỏ bản thân và tôi không hiểu tại sao. Một cái gì đó nói với tôi tôi đang trì hoãn nó một cách sai lầm.
EDIT2
Nhờ có sự liên kết @EugenMatynov cho tôi: update ui from another thread in android tôi đã hiểu tại sao các ứng dụng bỏ hoạt. Tất cả đều đi xuống lý do Bạn không thể gọi các phương thức giao diện người dùng từ các chủ đề khác ngoài chuỗi chính. và thực tiễn không tốt để cập nhật giao diện người dùng từ một chuỗi khác.
sạch xử lý của hàng đợi trên onPause, và bạn đang bị rò rỉ 100% miễn phí. Trong trường hợp này. – Blackbelt
Không có rò rỉ bộ nhớ nào trong trường văn bản tĩnh? – stevehs17