【问题标题】:Thread.sleep stops all nested AsyntasksThread.sleep 停止所有嵌套的异步任务
【发布时间】:2015-09-19 00:54:54
【问题描述】:

我正在关注 codelearn 中的教程,并尝试创建一个 AsyncTask 来生成推文并执行另一个 AsyncTask 以写入缓存文件。 我有 Thread.sleep,所以第一次加载时的 UI 会等到推文被写入缓存文件。首先我执行 AysncTask new AsyncWriteTweets(this.parent).execute(tweets); 然后休眠 10 秒。

但在 logcat 中,我可以看到 AsyncWriteTweets 也在 10 秒睡眠后执行。因此 onPostExecute 会在推文写入缓存文件之前执行,从而出现空白屏幕。

public class AsyncFetchTweets extends AsyncTask<Void, Void, Void> {
    private TweetListActivity parent;
    ArrayList<Tweet> tweets = new ArrayList<Tweet>();
    ArrayList[] temp;

    public AsyncFetchTweets(TweetListActivity parent){
        this.parent = parent;
    }

    @Override
    protected Void doInBackground(Void... params) {
        int result = 0;
        Log.d("ASync", "Calling asycn");
        for (int i=0;i<4;i++){
            Tweet tweet = new Tweet();
            tweet.setTitle("Title Async Very New" + i);
            tweet.setBody("Body text for tweet no " + i);
            tweets.add(tweet);
        }
        new AsyncWriteTweets(this.parent).execute(tweets);

        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return null;
    }

    protected void onPostExecute(Void result){
        Log.d("Async", "on Post execute");
        this.parent.renderTweets();
    }

}

PS:我的假设是 AsyncTask 应该创建一个新线程,因此 父级中的 Thread.sleep 不应阻止子级。如果不是这样 请告知我该如何解决这个问题。

【问题讨论】:

    标签: java android multithreading android-asynctask


    【解决方案1】:

    根据execute() 方法的文档,单个线程用于所有异步任务。因此,如果您在异步任务中处于休眠状态,则会影响其他异步任务。

    试试executeOnExecutor

    【讨论】:

      【解决方案2】:

      这个:

      new AsyncWriteTweets(this.parent).execute(tweets);
      

      错了,AsyncTask 必须在 UI 线程而不是 Worker 线程上执行。您可以使用 Handler 和 post runnable 来安全地执行它。

      查看线程规则作为参考:

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

      http://developer.android.com/reference/android/os/AsyncTask.html

      上面感兴趣的链接的另一部分是Order of execution,:

      从 HONEYCOMB 开始,任务在单线程上执行,以避免并行执行导致的常见应用程序错误。

      所以您的第一个异步任务必须在下一个异步任务开始之前结束,但是您可以通过使用 executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR. 恢复之前的并行行为,但 execute 必须在 UI 线程上完成。

      【讨论】:

      • 已编辑的答案是解决方案,我正在输入它,@marcinj 在我可以之前进行了编辑。 :+1
      • 感谢@marcinj 现在尝试
      猜你喜欢
      • 1970-01-01
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-16
      • 2011-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多