fatal exception in android Timer

2019-03-04 17:39发布

问题:

in my android application i'm using Timer schedule.but getting Timer-0 fatal exception as below.how can i remove it.i have also mentioned code below -

01-28 13:44:41.142: E/AndroidRuntime(1307): FATAL EXCEPTION: Timer-0
01-28 13:44:41.142: E/AndroidRuntime(1307):android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
01-28 13:44:41.142: E/AndroidRuntime(1307):     at android.view.ViewRoot.checkThread(ViewRoot.java:2932)
01-28 13:44:41.142: E/AndroidRuntime(1307):     at android.view.ViewRoot.invalidateChild(ViewRoot.java:642)
01-28 13:44:41.142: E/AndroidRuntime(1307):     at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:668)
01-28 13:44:41.142: E/AndroidRuntime(1307):     at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
01-28 13:44:41.142: E/AndroidRuntime(1307):     at android.view.View.invalidate(View.java:5279)
01-28 13:44:41.142: E/AndroidRuntime(1307):     at android.view.View.setBackgroundDrawable(View.java:7626)
01-28 13:44:41.142: E/AndroidRuntime(1307):     at android.view.View.setBackgroundResource(View.java:7535)
01-28 13:44:41.142: E/AndroidRuntime(1307):     at com.example.iqtest.PlayGame$1.run(PlayGame.java:61)
01-28 13:44:41.142: E/AndroidRuntime(1307):     at java.util.Timer$TimerImpl.run(Timer.java:284)

and code is-

protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.next);
    but1=(Button) findViewById(R.id.b1);
    but2=(Button) findViewById(R.id.b2);
    but3=(Button) findViewById(R.id.b3);

    myTimer = new Timer();

    myTimer.schedule(new TimerTask() {      

        @Override
        public void run() {
            Random rand=new Random();
            int num=rand.nextInt(9)+1;

            num = rand.nextInt(buttonIds.length);
            int buttonId = buttonIds[num];
            Button bb=(Button) findViewById(buttonId);

            Drawable a=bb.getBackground();
            if(getResources().getDrawable(R.drawable.happy).equals(a))
             bb.setBackgroundResource(R.drawable.happy);
            else
                bb.setBackgroundResource(R.drawable.whoa);
        }
    },0, 1000);
}

回答1:

use runOnUiThread for updating UI element from Timertask run Method as :

 myTimer.schedule(new TimerTask() {      

 @Override
 public void run() {
  Current_Activity.this.runOnUiThread(new Runnable() {
    public void run() {
        // update UI here
    }
 });
 }
},0, 1000);


回答2:

You can use a CountDownTimer instead of the Timer :

Timer timer = new CountDownTimer(Long.MAX_VALUE, 1000) {
    public void onTick(long millisUntilFinished) {
        // the code in the method run
    }

    public void onFinish() {

    }
};

The methods onTick and onFinish will be called in the UI thread.

To make the timer start performing its action, run: timer.start()



回答3:

It is very simple, you are scheduling the Timer but not cancelling it never. So Task scheduled will be in the queue and wait for its turn. By that time it should get executed your Activity might not be in the foreground and it is unable to find the views. So it is throwing the Fatal Exception. Inorder, to get rid of the above issue, you need to cancel the tasks whenever you are going from that particular activity by calling myTimer.cancel().

Or else

Use the Handler class.



回答4:

runOnUiThread(new Runnable() {
     public void run() {

       //stuff that updates ui

    }
});

try this

also look at

Android "Only the original thread that created a view hierarchy can touch its views."

CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch views

Only the original thread that created a view hierarchy can touch its views



标签: android timer