如何从静态方法更改 TextView 文本?

How to change TextView Text from static method?

我的应用程序中有一个不断增加的值,执行此操作的处理程序位于我的“EventHandlerClass.java”中的静态方法中。 我现在想在我的 MainActivity 中的 TextView 上显示这个值。

这是我的处理程序静态方法:

public static void pointsCounter() {
        handler = new Handler(Looper.getMainLooper());

        runnable = new Runnable() {
            public void run() {
                points = points + 5;
                String pointMsg = "Points: " + points;
                MainActivity.coinsTextView.setText(pointMsg);
                 
                handler.postDelayed(this, 1000);
            }
        };
        handler.postDelayed(runnable, 1000);
    }

这个 pointsCounter 方法是从 EventHandlerClass.java 中的另一个静态方法调用的。

它每秒增加点值 +5,我希望它显示在 TextView 中。 正确的做法是什么? 因为当我以这种方式尝试时,我必须将 MainActivity 中的 coinsTextView 设为静态,我们都知道您不能从静态上下文中引用非静态变量。 当我这样做时,它告诉我“不要在静态字段中放置 Android 上下文 类;这是内存泄漏”。 所以我的问题是如何在不冒内存泄漏风险的情况下从静态方法更新我的 UI 元素? 正确的做法是什么?

正如您所说,切勿在您的应用程序中放置静态视图或上下文,因为它会导致异常内存泄漏,但是如果您仍想在您的应用程序中使用静态 TextView,您可以将 TextView 包装在 WeakReference 中:

WeakReference:弱引用是一种引用的强度不足以将对象保存在内存中。如果我们试图确定该对象是否被强引用并且碰巧是通过 WeakReferences,该对象将被垃圾回收。 这是一个如何使用它的例子:

public class MainActivity extends AppCompatActivity {
    private static WeakReference<TextView> viewWeakReference;
    private static Handler handler;
    private static int points;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        
        textView = findViewById(R.id.textV);
        viewWeakReference = new WeakReference<>(textView);
        pointsCounter();
    }


    public static void pointsCounter() {
        handler = new Handler(Looper.getMainLooper());

        Runnable runnable = new Runnable() {
            public void run() {
                points = points + 5;
                String pointMsg = "Points: " + points;
                viewWeakReference.get().setText(pointMsg);
                handler.postDelayed(this, 1000);
            }
        };
        handler.postDelayed(runnable, 1000);
    }
}