2

I have a timer that I want to start an AsyncTask when the countdown is done. If I put the execution of it in a handler it loops it and starts it many times. And if I dont put it in a Handler I get the following crash: can't create handler inside thread that has not called looper.prepare()

timer.schedule(new ListUpdate(), helper.nextListUpdate.get(0));

class ListUpdate extends TimerTask {
    private Handler mHandler = new Handler(Looper.getMainLooper());
    public void run() {
        mHandler.post(new Runnable() {
            public void run() {
                AsyncTask<Integer, Void, Boolean> task = new updateList();
                task.execute();
            }
        });
    }
}

Any suggestions of how I can solve this?

just_user
  • 11,769
  • 19
  • 90
  • 135

2 Answers2

5

AsyncTask is supposed to run on UI thread only. In your case, seems like you are not running it properly on a UI thread.

Perhaps try it like this:

timer.schedule(new ListUpdate(), helper.nextListUpdate.get(0));

class ListUpdate extends TimerTask {
    Looper looper = Looper.getMainLooper();
    looper.prepareMainLooper();

    private Handler mHandler = new Handler(looper);
    public void run() {
        mHandler.post(new Runnable() {
            public void run() {
                AsyncTask<Integer, Void, Boolean> task = new updateList();
                task.execute();
            }
        });
    }
}
waqaslam
  • 67,549
  • 16
  • 165
  • 178
  • 1
    This results in the following error. But its the closest to make it work so far:Only the original thread that created a view hierarchy can touch its views. – just_user May 08 '12 at 10:54
  • then i would suggest you to skip `looper.prepareMainLooper();` and in Async's **doInBackground** method, call `Looper.prepare(); Looper.loop();` and see if it works. For more info read [this](http://stackoverflow.com/questions/6766002/android-difference-between-getmainlooper-and-looper-mylooper) – waqaslam May 08 '12 at 11:07
  • why use a timertask for this ? You have a handler, use it ! – njzk2 Nov 23 '12 at 11:10
  • timertask is for initiating something at some point in future and he was using handler. But the problem was that his handler wasn't attached to a looper that is looping on a UI thread and that is the reason he couldn't execute AsyncTask (because AsyncTasks only run on UI thread). I know its a little messy solution but the idea is to inform OP that you need a looper that loops on a UI thread :) – waqaslam Nov 23 '12 at 11:22
0

By adding a handler outside of the TimerTask which I call from the TimerTask I could make it work!

final Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        RelativeLayout rl_header = (RelativeLayout)findViewById(R.id.rl_header);
        Desktop desktop = helper.getDesktop();
        try {
            desktop.inflate(ll, rl_header, banners, DesktopApp.this);
            Collections.sort(helper.nextListUpdate);
            helper.nextListUpdate.remove(0);
            timer = new Timer();
            if (helper.nextListUpdate.size() > 0) timer.schedule(new ListUpdate(), helper.nextListUpdate.get(0));
        } catch (Exception e) {
            e.printStackTrace();
        }
     }

};

class ListUpdate extends TimerTask {
    public void run() {
        DesktopApp.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                handler.sendEmptyMessage(0);
            }
        });
    }
}
just_user
  • 11,769
  • 19
  • 90
  • 135