【问题标题】:Start AsyncTask in TimerTask在 TimerTask 中启动 AsyncTask
【发布时间】:2012-05-09 15:40:39
【问题描述】:

我有一个计时器,我想在倒计时完成后启动 AsyncTask。如果我将它的执行放在一个处理程序中,它会循环它并多次启动它。如果我不把它放在处理程序中,我会遇到以下崩溃: 无法在未调用 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();
            }
        });
    }
}

关于如何解决这个问题的任何建议?

【问题讨论】:

  • 检查 this one 并让它工作
  • 您收到此错误是因为您无法在 Thread.u 中更新您的 UI。您需要从处理程序更新 UI
  • 我会将您的答案放在我的代码中的什么位置?
  • 是的,但我需要关于如何解决它的建议,而不是它发生的原因!
  • 更新UI的部分应该放在runOnUiThread()里面

标签: android


【解决方案1】:

AsyncTask 应该只在 UI 线程上运行。在您的情况下,您似乎没有在 UI 线程上正确运行它。

或许可以这样尝试:

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();
            }
        });
    }
}

【讨论】:

  • 这会导致以下错误。但它是迄今为止最接近它的工作:只有创建视图层次结构的原始线程才能接触它的视图。
  • 那么我建议你跳过looper.prepareMainLooper(); 并在Async 的doInBackground 方法中调用Looper.prepare(); Looper.loop(); 看看它是否有效。欲了解更多信息,请阅读this
  • 为什么要为此使用 timertask ?你有一个处理程序,使用它!
  • timertask 用于在将来的某个时间点启动某些东西,他正在使用处理程序。但问题是他的处理程序没有连接到在 UI 线程上循环的 looper,这就是他无法执行 AsyncTask 的原因(因为 AsyncTasks 只在 UI 线程上运行)。我知道它的解决方案有点混乱,但我的想法是通知 OP 你需要一个在 UI 线程上循环的 looper :)
【解决方案2】:

通过在 TimerTask 之外添加一个处理程序,我可以从 TimerTask 调用它!

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);
            }
        });
    }
}

【讨论】:

  • 为什么每个人都同时使用 timertasks 和 handlers?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-29
  • 1970-01-01
相关资源
最近更新 更多