定时器和异步在一起

时间:2012-11-23 10:30:28

标签: android timer

我想在Timer线程中触发AsynTask,我收到以下错误。

java.lang.ExceptionInInitializerError 引起:java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序

有可能吗? 这是我的代码

networkTimer = new Timer();
                networkTimer.schedule(new TimerTask() {
                    int counter = 1;
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        if(isNetworkAvailable()){
                            Log.d("Hey I got the Network","!!");
                            new GmailAsync().execute("");
                            networkTimer.cancel();
                        }else{
                            Log.d("Attempt","No:"+counter);
                            counter++;
                            if(counter == 6){
                                Log.d("Attempt","Finished");
                                networkTimer.cancel();
                            }
                        }
                    }
                },0, 5000);

2 个答案:

答案 0 :(得分:1)

必须在UI线程上运行

AsyncTask.execute(),而TimerTask则不会这样做。

建议: *使用runOnUiThread返回UI线程以使用您的AsyncTask *不要使用计时器,而是使用处理程序和postDelyaed *如果您不需要与UI交互,请不要使用AsyncTask(您可以,但我不知道您的AsyncTask会做什么。

最佳解决方案是#2。那看起来像是:

mHandler.postDelayed(new Runnable() {
    @Override
    public void run() {
        if(isNetworkAvailable()){
            Log.d("Hey I got the Network","!!");
            new GmailAsync().execute("");
        }else{
            Log.d("Attempt","No:"+counter);
            counter++;
            if(counter == 6){
                Log.d("Attempt","Finished");
            } else {
                mHandler.postDelayed(this, 5000);
            }
        }
    }, 5000);
}

只要反击< 6,runnable repost本身

答案 1 :(得分:0)

只需将每个调用包装到FinderMain $ 1.gotLocation或在Runnable中创建AsyncTask,然后将其发布到绑定到UI线程的Handler,如下所示:

class GetLastLocation extends TimerTask {
    private Handler mHandler = new Handler(Looper.getMainLooper());

        @Override
        public void run() {
           // ...
           mHandler.post(new Runnable() {
              public void run() {
                  locationResult.gotLocation(null);
              }
           });
           // ...
         }
    }