0

I'm using Android Studio and emulator android 4.1.2. My code

    Timer timer = new Timer ();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            myRun();
        }
    },10000,10000);

result in "unfortunately, app has stopped", however I found out the code

    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        public void run() {
            myRun();
        }
    }, 2000);

runs ok and displays as I expect. What is the inner difference between the two?

P.S.

public void myRun () {
    myView.removeAllViews();
    drawView = new DrawView(myContext, myView);
    myView.addView(drawView);
}

I'm trying to perpetually update a custom view until user cancels it. Just cycle

while (myRun) {

results in emulator becoming unresponsive to even back button, running that update in second thread

new Thread(new Runnable() {
        @Override
        public void run() {
            while (myRun) {

                myView.post(new Runnable() {
                    public void run() {
                        myView.removeAllViews();
                        drawView = new DrawView(myContext, myView);
                        myView.addView(drawView);
                    }
                });

            }
        }
    }).start();

results in same (interestingly to me, if I run debug with breakpoint on while in second thread, screen updates as I expect many times, however running w/out debugging does not update screen).

Alex Martian
  • 3,423
  • 7
  • 36
  • 71

2 Answers2

0

Timer executes its tasks on a separate thread that is used only for serving tasks created by this particular timer. Handler runs its task on its Looper's thread which may or may not be a UI thread. Generally speaking there's no much difference between this two classes if you use Handler on a separate thread. But it's more common in Android to use Handler and HandlerThread.

If you need to interact with UI, you'd better use Handler.

Akshay Bhat 'AB'
  • 2,690
  • 3
  • 20
  • 32
0

This is an interesting question and answer lies in Thread/GUI policy that android follows.

As we know, UI runs on main thread. Timer creates a different thread and android does not allow to update UI in a different thread. Why?

Suppose, you have started a thread in your activity that updates a TextView and while the thread is running you move to some other app. Now, main thread no longer exists and when the other thread tries to update the TextView it is not able to find that TextView. As a result, we see a crash.

Now let me come to the difference between TimerTask and Handler.

TimerTask creates a new thread, waits for the time specified and then executes run() method in the same thread. On the other hand, Handler creates a new thread, waits for specified duration then returns to main thread and executes run() method on MAIN thread(if handler is on main thread). Hence, it works fine.

However you can do it with timer too. See the code below:

final Runnable setRunnable = new Runnable() {
    public void run() {
         myView.removeAllViews();
         drawView = new DrawView(myContext, myView);
         myView.addView(drawView);
    }
};

TimerTask task = new TimerTask(){
    public void run() {
        getActivity().runOnUiThread(setRunnable);
    }
};

Timer timer = new Timer();
timer.schedule(task, 1000);

In this thread you are setting a runnable to run on UI thread after timer's duration.

Embydextrous
  • 1,611
  • 1
  • 12
  • 20