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