【问题标题】:Best practice for repeated network tasks?重复网络任务的最佳实践?
【发布时间】:2013-09-18 17:36:48
【问题描述】:

我有一个小型 Android 应用程序,我需要每隔几秒钟在其中执行一些 FTP 操作。 在了解了在 UI 线程上运行网络内容是 Android 不喜欢的艰难方式之后,我来到了这个解决方案:

// This class gets declared inside my Activity
private class CheckFtpTask extends AsyncTask<Void, Void, Void> {
    protected Void doInBackground(Void... dummy) {
        Thread.currentThread().setName("CheckFtpTask");
        // Here I'll do the FTP stuff       
        ftpStuff();
        return null;
    }
}

// Member variables inside my activity
private Handler checkFtpHandler;
private Runnable checkFtpRunnable;

// I set up the task later in some of my Activitiy's method:
checkFtpHandler = new Handler();
checkFtpRunnable = new Runnable() {
    @Override
    public void run() {
        new CheckFtpTask().execute((Void[])null);
        checkFtpHandler.postDelayed(checkFtpRunnable, 5000);
    }
};
checkFtpRunnable.run();

执行不能直接在 UI 线程上运行的重复性任务是一种好习惯吗? 此外,不是总是通过调用来创建新的 AsyncTask 对象

new CheckFtpTask().execute((Void[])null);

是否可以选择创建一次CheckFtpTask 对象然后重用它? 或者这会给我带来副作用吗?

提前致谢, 延斯。

【问题讨论】:

    标签: android multithreading android-asynctask android-networking


    【解决方案1】:

    是否可以选择创建一次 CheckFtpTask 对象然后重用它?或者这会给我带来副作用吗?

    不,会有副作用。 Quoting the docs线程规则:

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

    您只需要在每次想要运行它时创建一个单独的任务实例。

    我不确定您为什么需要RunnableHandler。如果您需要更新UIAsyncTask 具有在UI Thread 上运行的方法(实际上除了doInBackground())。

    Check this answer 如果您需要回调以在任务完成时更新UI

    【讨论】:

    • 为什么我需要RunnableHandler?好问题。我认为这将是使用postDelayed 重复执行任务的好方法。在doInBackground() 的循环内调用Thread.sleep() 会更好吗?不管怎样,就在我写这篇文章的时候,我发现了一个错误:在Runnable 中调用postDelayed() 是没有意义的。如果一项任务花费的时间超过 5 秒,则会在旧任务完成之前创建一个新任务。这不是我想要的,所以我将checkFtpHandler.postDelayed(checkFtpRunnable, 5000); 移到了AsyncTaskonPostExecute()
    • 整个任务(就像现在一样!)在 UI 上什么都不做。我只是选择了 AsyncTask 加上 Runnable/Handler 的组合,因为我需要一个 不在 UI 线程上recurring 任务与(稍后) 选项来做一些 UI 的东西。这听起来合理吗?
    • 您可以在doInBackground() 中调用Thread.sleep(),例如在for loopwhile loop 中重复此操作。
    • 但是当我有一个带有Thread.sleep() 的“inifinte 循环”时,我失去了做 UI 的能力,对吧?
    • 不,一点也不。您可以在任何其他AsyncTask 方法上更新UI,例如onProgressUpdate()onPostExecute()doInBackground() 是唯一一个不在 UI 上运行的 AsyncTask 方法
    【解决方案2】:

    您应该为每个调用创建一个新的异步任务。

    请参阅 Android 文档:AsyncTask。根据此文档:

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

    具体查看线程规则部分。这里有一个类似的答案,https://stackoverflow.com/a/18547396/2728623

    【讨论】:

      【解决方案3】:

      Java ThreadPools 和 ExecutorFramework 允许您根据需要执行线程并减少线程创建开销。 Check out the singleThreadExecutor。线程池使用情况为pretty easy too!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-18
        • 1970-01-01
        • 1970-01-01
        • 2010-10-08
        • 1970-01-01
        • 1970-01-01
        • 2016-06-28
        • 1970-01-01
        相关资源
        最近更新 更多