从两个活动中运行相同的后台任务

时间:2011-03-28 16:10:13

标签: android multithreading

在我的应用程序中,我有一个后台任务(使用AsyncTask)从网站下载内容。

可以从两个单独的活动中调用此任务,并且可以将其调用两次。因此在“activity1”中调用后台任务“update”,并运行一段时间(通常需要5-10秒)。 然后当它运行时,用户切换到“activity2”并再次运行“更新”。 这会产生问题:当两者同时尝试清除数据库(命令:DELETE FROM表)时发生崩溃,导致“数据库锁定”错误。或者他们试图将相同的项目放在数据库中导致重复。

我尝试通过在任务处于活动状态时将静态布尔标志设置为true来解决此问题。 当调用该任务时,它将检查此标志,如果为true(即在另一个线程上运行相同的任务),则使用处理程序进入等待循环,直到该标志清除,然后返回。这样可以确保在后台任务返回时,更新已完成。我必须使用一个Looper:这有时会失败并出现错误“每个线程只能创建一个looper”。我真的有这样一种方式,只有一个looper可以启动,这是有问题的代码,它出现在后台任务的开头:

    if (active) {
        Looper.prepare();
        handler = new Handler();
        handler.postDelayed(new Runnable() {
            int count = 0;

            @Override
            public void run() {
                if (active) {
                    count++;
                    if (count < 1000) 
                        handler.postDelayed(this, 100);
                }
            }
        }, 100);
        Looper.loop();
        active = false;
        return "done";
    }

更糟糕的是,它似乎常常挂在这个循环中,而不会返回。

如何解决这种情况?

3 个答案:

答案 0 :(得分:0)

为什么不使用同步?这听起来像是一个并发问题。为什么不确保如果第一个后台任务正在运行,那么第二个后台任务正在休眠,直到第一个任务完成为止。

或者以某种方式确保,如果用户切换到活动编号2,活动编号1的后台任务将被取消。

答案 1 :(得分:0)

您可以考虑使用IntentService代替AsyncTask。看看Android Service concept。 IntentService类确保一次只处理一个请求。

我发现this在使用Activity回调通信实现IntentService时非常有用。

答案 2 :(得分:0)

通过将数据库锁定问题包装到ContentProvider中解决了这个问题。除了在前一个实例完成之前再次调用方法的问题之外,我还遇到了在尝试写入数据库时​​在不同后台线程中运行的不同方法的问题。

官方设计允许在应用之间共享数据,它也非常适合在单个应用中的线程之间共享数据。 ContentProvider将确保不会发生锁定问题。