我正在研究用于网络层的改装。有没有办法在任何时候告诉我一个特定的异步请求是否正在运行?例如,我想知道请求是否正在运行,以便我可以在不同的时间更新用户界面。我可以通过保留变量来跟踪状态来自己完成这个过程,但想知道库中是否已经有相关功能。
我正在研究用于网络层的改装。有没有办法在任何时候告诉我一个特定的异步请求是否正在运行?例如,我想知道请求是否正在运行,以便我可以在不同的时间更新用户界面。我可以通过保留变量来跟踪状态来自己完成这个过程,但想知道库中是否已经有相关功能。
当我需要一种方式来跟踪正在运行的请求时,通常会这样做:
您可以在此处找到EventBus。
希望这有所帮助!
在这种情况下,我个人最终采用的方法是使用Retrofit、Android Priority Jobqueue(来自yigit的分支)和Otto事件总线运行示例。
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来跟踪作业是否正在运行。
此外,我还没有弄清楚如何正确使用持久性作业进行依赖注入;我也不知道他们打算如何使其工作。当然,如果它使用应用程序范围组件而不是提供的Presenter范围组件,那么它就可以工作,但这是无关紧要的。
您可能需要根据自己的情况自定义此解决方案,并仅使用实际所需的内容。