Я создал автономный веб-просмотр в приложении для Android, чтобы вычистить URL-адрес с веб-страницы. Каждый раз, когда я получаю URL-адрес, мне может потребоваться повторная очистка веб-страницы с этим URL-адресом. Я использую RxJava для одновременной обработки этих операций и использую функцию flatMap
для рекурсивного вызова.
Проблема в том, что мне нужно избавиться от WebView в mainThread, поэтому я попытался добавить .unsubscribeOn(AndroidSchedulers.mainThread())
, но, похоже, это не работает, и метод dispose()
в HeadlessRequest
вызывается в последнем потоке Я позвонил observeOn(Schedulers.computation())
. Что я должен изменить, чтобы выполнить метод dispose()
в mainThread?
Это мой код:
HeadlessRequest
public class HeadlessRequest implements Disposable {
...
private class HeadlessWebView extends WebView {
...
private void destroyWebView() {
this.removeAllViews();
this.clearCache(false);
this.loadUrl("about:blank");
this.onPause();
this.removeAllViews();
this.destroy();
this.isDisposed = true;
}
}
@Override
public void dispose() {
// This doesn't print the mainThread id
Log.d(TAG, "Disposing on thread " + Thread.currentThread().getId());
this.webView.destroyWebView();
this.webView = null;
}
@Override
public boolean isDisposed() {
return (this.webView == null || this.webView.isDisposed);
}
}
NetworkUtils
public static Single<Document> downloadPageHeadless(final String url, final int delay, final Context context) {
return Single.create((SingleEmitter<Document> emitter) -> {
try {
emitter.setDisposable(new HeadlessRequest(url, USER_AGENT, delay, context, emitter::onSuccess, emitter::onError));
} catch (Exception e) {
emitter.onError(e);
}
}).unsubscribeOn(AndroidSchedulers.mainThread()) // It MUST be executed on the mainThread
.subscribeOn(AndroidSchedulers.mainThread());
}
ServerService
private static Single<String> resolveRecursive(String url, Context context) {
Server server = getServerInstance(url, context);
if (server == null) {
return Single.error(new UnsupportedOperationException("Server for " + url + " not supported"));
} else if (server.isVideo()) {
return server.resolve(url, context); // This method return a Single with observeOn(Schedulers.computation())
} else {
return server.resolve(url, context)
.observeOn(Schedulers.computation())
.flatMap(resolvedUrl -> resolveRecursive(resolvedUrl, context));
}
}
public static Single<String> resolveURL(String url, Context context) {
return resolveRecursive(url, context)
.observeOn(AndroidSchedulers.mainThread());
}