最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Does using the Java Class Timer() on an android app make it slow, inefficient or unideal? - Stack Overflow

programmeradmin3浏览0评论

I am creating an android app with Java in Android Studio, where I am planning to have a scripted progress bar. When it comes to python, using time.sleep() in a tkinter GUI slows and lags down the app if not done with threading, I wonder if there are any such consequences here if I just normally implement it. If there are no consequences as such I want to know why and If there are, what can I do.

Relatively new to how android apps work.

I am creating an android app with Java in Android Studio, where I am planning to have a scripted progress bar. When it comes to python, using time.sleep() in a tkinter GUI slows and lags down the app if not done with threading, I wonder if there are any such consequences here if I just normally implement it. If there are no consequences as such I want to know why and If there are, what can I do.

Relatively new to how android apps work.

Share Improve this question edited 2 days ago Belal Ahmed asked 2 days ago Belal AhmedBelal Ahmed 3091 gold badge3 silver badges10 bronze badges 2
  • 1 If you call time.sleep() in a non-threaded application, then everything stops until the sleep time expires. If you want to show a progress bar correctly then you probably need a background worker and event signals, to tell the GUI when to update the bar's image. – OldBoy Commented 2 days ago
  • I believe you either misunderstood the question or I did not make it clear enough that I was asking about the android app and not the tkinter GUI, I used it as an example. – Belal Ahmed Commented 2 days ago
Add a comment  | 

2 Answers 2

Reset to default 3

Using java.util.Timer in an Android app isn't ideal and can lead to inefficiencies. The Timer class creates a single background thread to execute tasks, which can become problematic if a task takes too long or throws an uncaught exception; this can terminate the timer's thread, causing subsequent tasks to be silently suppressed. Additionally, Timer doesn't integrate well with Android's lifecycle, making it less suitable for tasks that need to interact with the UI or be aware of the app's state.

A more robust and flexible alternative is ScheduledThreadPoolExecutor, which is part of the java.util.concurrent package. This class allows for better management of multiple scheduled tasks, provides a pool of threads to handle tasks concurrently, and offers improved error handling. It also integrates more seamlessly with Android's components.

For tasks that need to run on the main thread, such as updating the UI, consider using Handler or HandlerThread. Handler allows you to post tasks to the main thread's message queue, ensuring that UI updates are performed safely and efficiently. HandlerThread is a handy utility if you need a background thread with a looper.

In summary, while java.util.Timer can be used for simple scheduling, it's generally better to use ScheduledThreadPoolExecutor for more control and reliability, especially in the context of Android applications. For UI-related tasks, `Handler is the preferred choice to ensure smooth and responsive user experiences.

Yes, using Timer() in Android can cause performance issues, and it is not ideal for UI updates. Here’s why and how to properly handle it.


Why Using Timer() Can Be a Problem in Android?

  • Timer runs tasks on a separate thread but cannot update UI elements (like ProgressBar) directly.
  • If you try to update UI elements from a TimerTask, you will get an error: "Only the original thread that created a view hierarchy can touch its views."
  • If you use sleep() in the main thread (like time.sleep() in Python), it will freeze the UI, making the app feel laggy.

What is the Best Alternative?

  • Instead of Timer(), use: ✅ Handler with postDelayed() (Recommended for simple periodic tasks)
  • ✅ CountDownTimer (Best for progress bars & timers)
  • ✅ ScheduledExecutorService (More flexible alternative to Timer)

Best Solutions for Your Use Case (Updating a ProgressBar)

1️⃣ Using Handler.postDelayed() (Recommended)

Java:

Handler handler = new Handler();
int progress = 0;

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        if (progress <= 100) {
            progressBar.setProgress(progress);
            progress += 5;
            handler.postDelayed(this, 500);
        }
    }
};
handler.post(runnable);

Kotlin:

val handler = Handler(Looper.getMainLooper()) 
var progress = 0

val runnable = object : Runnable {
    override fun run() {
        if (progress <= 100) {
            progressBar.progress = progress
            progress += 5
            handler.postDelayed(this, 500)
        }
    }
}

handler.post(runnable)

2️⃣ Using CountDownTimer (Best for a Timed Progress Bar)

Java

new CountDownTimer(10000, 500) { // Total 10 sec, tick every 500ms
    public void onTick(long millisUntilFinished) {
        int progress = (int) ((10000 - millisUntilFinished) / 100);
        progressBar.setProgress(progress);
    }

    public void onFinish() {
        progressBar.setProgress(100);
    }
}.start();

Kotlin

object : CountDownTimer(10000, 500) {
    override fun onTick(millisUntilFinished: Long) {
        val progress = ((10000 - millisUntilFinished) / 100).toInt()
        progressBar.progress = progress
    }

    override fun onFinish() {
        progressBar.progress = 100
    }
}.start()

3️⃣ Using ScheduledExecutorService (Better than Timer)

Java:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        runOnUiThread(() -> {
            if (progress <= 100) {
                progressBar.setProgress(progress);
                progress += 5;
            }
        });
    }
}, 0, 500, TimeUnit.MILLISECONDS);

Kotlin:

val scheduler = Executors.newScheduledThreadPool(1)
var progress = 0

scheduler.scheduleAtFixedRate({
    runOnUiThread {
        if (progress <= 100) {
            progressBar.progress = progress
            progress += 5
        }
    }
}, 0, 500, TimeUnit.MILLISECONDS)

4️⃣ Using Coroutine & delay() (Recommended for Modern Kotlin)

import kotlinx.coroutines.*

var progress = 0

fun startProgressBar() {
    GlobalScope.launch(Dispatchers.Main) {
        while (progress <= 100) {
            progressBar.progress = progress
            progress += 5
            delay(500L)
        }
    }
}

Conclusion

❌ Timer() is not ideal because it runs on a background thread, making UI updates problematic.

✅ Instead, use:

  • Handler.postDelayed() for simple repeated UI updates.
  • CountDownTimer for fixed-time progress bars.
  • ScheduledExecutorService for background tasks.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论