我正在考虑对我的网络层进行改造。有什么方法可以判断特定的异步请求是否在任何给定时刻运行?
例如,我想知道请求是否正在运行,以便我可以在不同时间更新用户界面。我可以自己通过保持变量来跟踪状态来做到这一点,但想知道库中是否已经有一些东西。
我正在考虑对我的网络层进行改造。有什么方法可以判断特定的异步请求是否在任何给定时刻运行?
例如,我想知道请求是否正在运行,以便我可以在不同时间更新用户界面。我可以自己通过保持变量来跟踪状态来做到这一点,但想知道库中是否已经有一些东西。
当需要一种方法来跟踪正在运行的请求时,我通常会这样做:
你可以在这里找到 EventBus
我希望这有帮助!
在这种情况下,我个人最终做的是使用 Retrofit、Android Priority Jobqueue(来自 yigit 的 fork)和 Otto eventbus 运行示例。
public enum SingletonBus {
INSTANCE;
private Bus bus;
private Handler handler = new Handler(Looper.getMainLooper());
private SingletonBus() {
this.bus = new Bus(ThreadEnforcer.ANY);
}
public <T> void postToSameThread(final T event) {
bus.post(event);
}
public <T> void postToMainThread(final T event) {
handler.post(new Runnable() {
@Override
public void run() {
bus.post(event);
}
});
}
public <T> void register(T subscriber) {
bus.register(subscriber);
}
public <T> void unregister(T subscriber) {
bus.unregister(subscriber);
}
}
public interface Interactor {
void injectWith(PresenterComponent presenterComponent);
}
public interface SendCertificateRequestInteractor
extends Interactor {
interface Listener {
void onSuccessfulEvent(SuccessfulEvent e);
void onFailureEvent(FailureEvent e);
}
class SuccessfulEvent
extends EventResult<CertificateBO> {
public SuccessfulEvent(CertificateBO certificateBO) {
super(certificateBO);
}
}
class FailureEvent
extends EventResult<Throwable> {
public FailureEvent(Throwable throwable) {
super(throwable);
}
}
void sendCertificateRequest(String username, String password);
}
注意Job
这里:
public class SendCertificateRequestInteractorImpl
implements SendCertificateRequestInteractor {
private Presenter presenter;
private boolean isInjected = false;
@Inject
public JobManager jobManager;
public SendCertificateRequestInteractorImpl(Presenter presenter) {
this.presenter = presenter;
}
@Override
public void sendCertificateRequest(String username, String password) {
if(!isInjected) {
injectWith(presenter.getPresenterComponent());
isInjected = true;
}
InteractorJob interactorJob = new InteractorJob(presenter, username, password);
long jobId = jobManager.addJob(interactorJob); //this is where you can get your jobId for querying the status of the task if you want
}
@Override
public void injectWith(PresenterComponent presenterComponent) {
presenterComponent.inject(this);
}
public static class InteractorJob
extends Job {
private final static int PRIORITY = 1;
private final static String TAG = InteractorJob.class.getSimpleName();
private String username;
private String password;
@Inject
public MyService myService;
public InteractorJob(Presenter presenter, String username, String password) {
super(new Params(PRIORITY).requireNetwork());
presenter.getPresenterComponent().inject(this);
this.username = username;
this.password = password;
}
@Override
public void onAdded() {
// Job has been saved to disk.
// This is a good place to dispatch a UI event to indicate the job will eventually run.
// In this example, it would be good to update the UI with the newly posted tweet.
}
@Override
public void onRun()
throws Throwable {
String certificate = myService.getCertificate(username, password);
SingletonBus.INSTANCE.postToMainThread(new SuccessfulEvent(certificate));
}
@Override
protected void onCancel() {
// Job has exceeded retry attempts or shouldReRunOnThrowable() has returned false.
Log.e(TAG, "Cancelled job.");
}
@Override
protected boolean shouldReRunOnThrowable(Throwable throwable) {
// An error occurred in onRun.
// Return value determines whether this job should retry running (true) or abort (false).
Log.e(TAG, "Failed to execute job.", throwable);
SingletonBus.INSTANCE.postToMainThread(new FailureEvent(throwable));
return false;
}
}
}
接着
@Subscribe
@Override
public void onSuccessfulEvent(SendCertificateRequestInteractor.SuccessfulEvent e) {
String certificate = e.getResult();
//do things
}
@Subscribe
@Override
public void onFailureEvent(SendCertificateRequestInteractor.FailureEvent e) {
Throwable throwable = e.getResult();
//handle error
}
更多关于android priority jobqueue
这里。
这样,从技术上讲,异步处理是指作业队列,而 Retrofit 本身使用的是同步接口。只要您不需要访问响应的标头,它就可以很好地工作。虽然公平地说,我还在跟踪作业是否使用布尔值而不是作业管理器和 id 运行。
另外,我还没有弄清楚如何在持久作业中正确使用依赖注入;我也不知道他们打算如何进行这项工作。当然,如果它使用应用程序范围的组件而不是提供的演示者范围的组件,它会起作用,但这无关紧要。
您可能需要根据自己的场景自定义此解决方案,并仅使用您实际需要的内容。