为了账号安全,请及时绑定邮箱和手机立即绑定

多次执行AsyncTask

多次执行AsyncTask

呼如林 2019-09-20 15:41:45
在我的Activity中,我使用了一个从AsyncTask扩展的类和一个参数,该参数是AsyncTask的一个实例。我打电话的时候mInstanceOfAT.execute("")一切都很好。但是当我按下再次调用AsyncTask的更新按钮时应用程序崩溃(如果网络作业不起作用)。因此出现了一个例外情况无法执行任务:任务已经执行(任务只能执行一次)我试过为Asyctask的实例调用cancel(true),但它也不起作用。到目前为止唯一的解决方案是创建Asyntask的新实例。这是正确的方法吗?谢谢
查看完整描述

3 回答

?
慕虎7371278

TA贡献1802条经验 获得超4个赞

AsyncTask 实例只能使用一次。


相反,只需将您的任务称为 new MyAsyncTask().execute("");


来自AsyncTask API文档:


线程规则

此类必须遵循一些线程规则才能正常工作:


必须在UI线程上创建任务实例。

必须在UI线程上调用execute(Params ...)。

不要手动调用onPreExecute(),onPostExecute(Result),doInBackground(Params ...),onProgressUpdate(Progress ...)。

该任务只能执行一次(如果尝试第二次执行,则会抛出异常。)


查看完整回答
反对 回复 2019-09-20
?
精慕HU

TA贡献1845条经验 获得超8个赞

在Steve Prentice的回答中详细说明了ASyncTask发生故障的实例 - 但是,当您执行ASyncTask的次数受到限制时,您可以在线程运行时自由地执行您喜欢的操作。 。


将可执行代码放在doInBackground()中的循环中,并使用并发锁来触发每次执行。您可以使用publishProgress()/ onProgressUpdate()检索结果。


例:


class GetDataFromServerTask extends AsyncTask<Input, Result, Void> {


    private final ReentrantLock lock = new ReentrantLock();

    private final Condition tryAgain = lock.newCondition();

    private volatile boolean finished = false;


    @Override

    protected Void doInBackground(Input... params) {


        lock.lockInterruptibly();


        do { 

            // This is the bulk of our task, request the data, and put in "result"

            Result result = ....


            // Return it to the activity thread using publishProgress()

            publishProgress(result);


            // At the end, we acquire a lock that will delay

            // the next execution until runAgain() is called..

            tryAgain.await();


        } while(!finished);


        lock.unlock();

    }


    @Override

    protected void onProgressUpdate(Result... result) 

    {

        // Treat this like onPostExecute(), do something with result


        // This is an example...

        if (result != whatWeWant && userWantsToTryAgain()) {

            runAgain();

        }

    }


    public void runAgain() {

        // Call this to request data from the server again

        tryAgain.signal();

    }


    public void terminateTask() {

        // The task will only finish when we call this method

        finished = true;

        lock.unlock();

    }


    @Override

    protected void onCancelled() {

        // Make sure we clean up if the task is killed

        terminateTask();

    }

}

当然,这比传统的ASyncTask使用稍微复杂一点,并且您放弃使用publishProgress()进行实际的进度报告。但是如果你担心内存,那么这种方法将确保在运行时只有一个ASyncTask保留在堆中。


查看完整回答
反对 回复 2019-09-20
?
慕仙森

TA贡献1827条经验 获得超8个赞

我遇到过同样的问题。就我而言,我有我想在做任务onCreate()和onResume()。所以我使我的Asynctask静态,并从中获取实例。现在我们仍然有同样的问题。


所以我在onPostExecute()中做的是这样的:


instance = null;

请记住,我检查静态getInstance方法,我的实例不为null,否则我创建它:


if (instance == null){

    instance = new Task();

}

return instance;

postExecute中的方法将清空实例并重新创建它。当然这可以在课外完成。


查看完整回答
反对 回复 2019-09-20
  • 3 回答
  • 0 关注
  • 809 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信