【问题标题】:Architecture for multiple http requests多个 http 请求的架构
【发布时间】:2014-05-21 07:11:44
【问题描述】:

我阅读了很多关于为异步操作创建正常架构的文章。 但是我还是有问题。

Web 上的大多数示例都显示了在 AsyncTask 的帮助下与 Web 服务的连接。 因此,当设备将其方向与横向更改为正常时,我们在重新创建 Activity 时使用这种简单的架构时遇到了麻烦,反之亦然。 当我们的任务已启动但用户按下后,我们也会遇到问题,我们丢失了有关当前 AsyncTask 的所有信息。

我想构建一个架构,您可以在其中简单地执行一些请求并在操作结束后对它调用的活动进行回调。 我打算使用 service 进行后台操作,ThreadExecutor 进行处理操作。

这是我发现的有关线程和后台操作的信息最丰富的链接。 http://www.slideshare.net/andersgoransson/efficient-android-threading

那么现在,您能告诉我一些实现这种方法的好代码示例吗?它可以没有任何 cmets(不是教程 mb 只是在 Github 上的项目),但有代码,看看如何实现。

【问题讨论】:

  • 我们公司正在开发通信框架,我们在其中采用了相同的方法 - 制作了我们自己的任务管理。我们使用 ExecutorService 来执行。我们还做了几种执行模式:有些任务必须按顺序执行(例如,当同一个远程主机上有多个请求时),或者并行执行。
  • @АндрейМосквичёв 你有一些源代码示例可以与我们分享吗?
  • 来源是专有的。我可以简要介绍一下我们所做的工作。
  • @АндрейМосквичёв 会很棒。我有兴趣阅读这篇文章。
  • 写了一篇关于我们如何制作它的描述。我希望这对你有帮助。如果您有任何问题,请随时提出。

标签: android multithreading asynchronous


【解决方案1】:

我们公司正在开发移动-网络-桌面通信框架,我们已经在其中进行了自己的异步任务管理。

Framework 与远程设备一起操作,本地和远程设备之间的每个事务都在 Transaction(AsyncTask 的扩展模拟)中执行。

TransactionManager 类保存所有事务并负责它们的执行。它有单线程和缓存线程池ExecutorService。如果事务被明确标记,它可以并行运行 - 它在缓存线程池(多线程模式)上运行,否则它在单线程执行器上运行。这样做是因为并非所有事务都可以多线程运行,并且如果它们以多线程模式运行(例如,当有多个事务时,会更改本地或远程设备的状态),则可能会产生副作用。

如何创建单缓存或固定 ExecutorService 可以在这里找到:Executors

TransactionManager 本身位于 Service 中。通过本地绑定连接到所有其他应用程序组件的服务,如此处所述Bound Services

每笔交易都有唯一标识符、参与设备、消息(现在执行的步骤,例如“连接”、“下载”、“上传”)、进度和状态。 状态可以是 NotStarted、Started、Error、Finished。 消息用于在 UI 中显示它 - 现在执行的操作。 唯一标识符 (uid) 用于查找交易或将交易信息发送到另一个活动,只需在意图中发送它的 uid。

我们解决了屏幕旋转问题如下:

protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

            // transaction manager holds all transactions
    TransactionManager transactionManager = commService.getTransactionManager();

    String lsTransactionId = savedInstanceState.getString(LS_TRANSACTION_ID);
    if (lsTransactionId != null) {
        lsTransaction = (OutgoingTransaction<FileItem[]>) transactionManager.getTransactionById(lsTransactionId);
        // update UI according to transaction state
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

            // if we have runnng transaction - store it's id to bundle
    if (lsTransaction != null) {
        outState.putString(LS_TRANSACTION_ID, lsTransaction.getId());
    }
}

Transaction 类具有执行实际工作(下载或上传数据等)的抽象方法 - 类似于 AsyncTask 的 doInBackground 方法。

事务有监听器来接收它的事件:

public interface TransactionListener<T> {
/**
 * Called when transaction is started.
 */
void started();

/**
 * Called when transaction message is posted by Transaction.setMessage call.
 * @param message message
 */
void message(String message);

/**
 * Called when transaction is finished.
 * @param result transaction result
 */
void finished(T result);

/**
 * Called when transaction is cancelled.
 */
void cancelled();

/**
 * Called when transaction error is occurred.
 * @param thr throwable indicating an error
 */
void error(Throwable thr);

/**
 * Called on transaction progress.
 * @param value progress value
 * @param total progress total
 */
void progress(long value, long total);
}

还有一件事——为了让监听器方法在 UI 线程上执行,我们制作了帮助类 AndroidTransactionListener,它使用 Handler.post 在 ui 线程上执行上述方法。关于 Handler 你可以在这里阅读:Handler

【讨论】:

  • 感谢您的回复。也许以后我会尝试编写自己的框架,以正确使用长时间的操作。现在我决定使用 Robospice,因为它可以缓存请求,是开箱即用的好工具。
【解决方案2】:

我为此使用了 Robospice。它具有您在服务级别附加到的侦听器,基本上在 onResume() 中。你向它发射任务,它会为你完成它们。设置工作量很大,但我发现它比大量手动线程更容易。

如果您有明确定义的响应,它还支持缓存。

【讨论】:

    【解决方案3】:

    Volley 库可以做你想做的事。如果你想要自己的图书馆,也有资源。

    【讨论】:

      猜你喜欢
      • 2017-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 1970-01-01
      • 1970-01-01
      • 2016-03-29
      相关资源
      最近更新 更多