ネットワーク層の改良を検討しています。特定の非同期リクエストが特定の時点で実行されているかどうかを確認する方法はありますか?
たとえば、さまざまなタイミングでユーザー インターフェイスを更新できるように、リクエストが実行されているかどうかを知りたいとします。状態を追跡するために変数を保持することでこれを自分で行うことができますが、これのためにライブラリに既に何かがあるかどうか疑問に思っています。
ネットワーク層の改良を検討しています。特定の非同期リクエストが特定の時点で実行されているかどうかを確認する方法はありますか?
たとえば、さまざまなタイミングでユーザー インターフェイスを更新できるように、リクエストが実行されているかどうかを知りたいとします。状態を追跡するために変数を保持することでこれを自分で行うことができますが、これのためにライブラリに既に何かがあるかどうか疑問に思っています。
実行中のリクエストを追跡する方法が必要な場合、通常は次のようにします。
ここでEventBusを見つけることができます
これが役立つことを願っています!
この場合、私が個人的に行ったことは、Retrofit、Android Priority Jobqueue (yigit のフォークから)、および 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の代わりにブール値でジョブが実行されているかどうかも追跡していました..
また、永続化されたジョブで依存性注入を適切に使用する方法もわかりません。また、彼らがどのようにそれを機能させるつもりだったのか、私には本当にわかりません。もちろん、提供されたプレゼンター スコープのコンポーネントではなく、アプリケーション スコープのコンポーネントを使用していれば機能しますが、それは関係ありません。
おそらく、このソリューションを独自のシナリオに合わせてカスタマイズし、実際に必要なものだけを使用する必要があります。