android CountDownTimer的这个实现是否正确处理了任何可能的内存泄漏?

c9x0cxw0  于 2023-08-01  发布在  Android
关注(0)|答案(1)|浏览(145)

嗨,我正在我的应用程序中创建一个倒计时计时器,我担心它可能会导致内存泄漏,因为我正在重用我的Activity中的同一个对象,通过创建一个新的倒计时计时器的新示例来恢复倒计时计时器,该示例的时间是用户停止前一个计时器时剩下的时间。
这是我的CountDownTimer实现:

public class MyActivity extends AppCompatActivity {
    private CountDownTimer myCountDownTimer;
    private long timeRemaining = 20000;
    private TextView mTextField;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        mTextField = findViewById(R.id.textViewTimer);

        createTimer(timeRemaining);

        Button pauseButton = findViewById(R.id.pauseButton);
        pauseButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (myCountDownTimer != null) {
                    myCountDownTimer.cancel();
                }
            }
        });

        Button resumeButton = findViewById(R.id.resumeButton);
        resumeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                createTimer(timeRemaining);
            }
        });
    }

    public void createTimer(long millisInFuture) {

        myCountDownTimer = new CountDownTimer(millisInFuture, 1000) {
            public void onTick(long millisUntilFinished) {
                mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
                timeRemaining = millisUntilFinished;
            }

            @Override
            public void onFinish() {
            }
        };

        myCountDownTimer.start();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (myCountDownTimer != null) {
            myCountDownTimer.cancel();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (myCountDownTimer != null) {
            myCountDownTimer.cancel();
            myCountDownTimer = null;
        }
    }
}

字符串
这个实现看起来是否很好,以便垃圾收集器能够正确地管理countdowntimer?

eagi6jfj

eagi6jfj1#

倒计时计时器的实现总体上看起来不错,但内存管理存在一个潜在问题,可能导致内存泄漏。
问题出在resumeButton单击侦听器中,在该侦听器中,每当用户单击恢复按钮时,您都会创建一个新的CountDownTimer示例。这可能会导致CountDownTimer的多个示例同时运行,并且旧示例可能无法正确取消,这可能会导致内存泄漏。
若要解决此问题,应确保在创建新CountDownTimer之前取消CountDownTimer的上一个示例。以下是如何修改代码以避免内存泄漏:

public class MyActivity extends AppCompatActivity {
    private CountDownTimer myCountDownTimer;
    private long timeRemaining = 20000;
    private TextView mTextField;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        mTextField = findViewById(R.id.textViewTimer);

        createTimer(timeRemaining);

        Button pauseButton = findViewById(R.id.pauseButton);
        pauseButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (myCountDownTimer != null) {
                    myCountDownTimer.cancel();
                }
            }
        });

        Button resumeButton = findViewById(R.id.resumeButton);
        resumeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (myCountDownTimer != null) {
                    myCountDownTimer.cancel();
                }
                createTimer(timeRemaining);
            }
        });
    }

    public void createTimer(long millisInFuture) {
        myCountDownTimer = new CountDownTimer(millisInFuture, 1000) {
            public void onTick(long millisUntilFinished) {
                mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
                timeRemaining = millisUntilFinished;
            }

            @Override
            public void onFinish() {
            }
        };

        myCountDownTimer.start();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (myCountDownTimer != null) {
            myCountDownTimer.cancel();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (myCountDownTimer != null) {
            myCountDownTimer.cancel();
            myCountDownTimer = null;
        }
    }
}

字符串
通过此修改,以前的CountDownTimer将在创建新的CountDownTimer之前被取消,从而防止多个计时器示例同时运行,并避免潜在的内存泄漏。
此外,确保处理用户暂停倒计时计时器但没有恢复的情况(例如,如果Activity暂停或销毁)。您可能需要根据您的特定用例调整行为。

相关问题