#android #android-webview #rx-java2 #headless-browser #unsubscribe
#Android #android-webview #rx-java2 #безголовый браузер #отписаться
Вопрос:
Я создал безголовый веб-просмотр в приложении Android для удаления URL-адреса с веб-страницы. Каждый раз, когда я получаю URL-адрес, мне может потребоваться повторить очистку веб-страницы с этим URL-адресом. Я использую RxJava для одновременной обработки этих операций, и я использую flatMap
функцию для выполнения рекурсивного вызова.
Проблема в том, что мне нужно удалить WebView в MainThread, поэтому я попытался добавить .unsubscribeOn(AndroidSchedulers.mainThread())
, но, похоже, это не работает, и dispose()
метод in HeadlessRequest
вызывается в последнем вызванном мной потоке observeOn(Schedulers.computation())
. Что я должен изменить, чтобы выполнить dispose()
метод в MainThread?
Это мой код:
Запрос без заголовка
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());
}
Ответ №1:
В конце я нашел другой способ удаления webview в MainThread без RxJava. Я использовал post
метод WebView.
private void destroyWebView() {
this.post(() -> {
this.removeAllViews();
this.clearCache(false);
this.loadUrl("about:blank");
this.onPause();
this.removeAllViews();
this.destroy();
this.isDisposed = true;
});
}