OnPageFinished не стрелять правильно при рендеринге веб-страницы
По какой-то причине onPageFinished увольняется до того, как WebView завершил загрузку - я не могу понять, почему...
public class WebViewClientTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final WebView webview = (WebView) findViewById(R.id.webview);
webview.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(webview, url);
webview.scrollTo(0, 500);
}
});
webview.loadUrl("http://www.google.co.uk/search?sourceid=chrome&ie=UTF-8&q=lala");
}
}
Хорошо, похоже, что это не исправлено. Я думаю, что при загрузке страницы происходит состояние гонки, но не может получить воспроизводимое поведение.
Я сохраняю HTML-содержимое веб-страницы в базе данных SQLite для просмотра в автономном режиме. Я перезагружаю содержимое в WebView с помощью:
webView.loadDataWithBaseURL("fake://fake.com/", htmlBody, "text/html", "utf-8", null);
Похоже, что иногда, когда WebView загружает, он корректно запускает метод WebViewClient.onPageFinished(), а в других случаях - нет. Иногда он срабатывает до того, как страница закончила загрузку, создавая contentHeight 0 и игнорируя любые вызовы scrollTo.
У кого-нибудь есть опыт?
Ответы
Ответ 1
У меня был проект с кодом, который должен был запускаться только после того, как веб-просмотр отобразил его содержимое, и, как и вы, onPageFinished() не работал. Он выстрелил слишком быстро, прежде чем веб-просмотр действительно отобразил страницу.
Вместо этого мне пришлось использовать "PictureListener", который запускается, когда веб-просмотр фактически обновляет экран.
Вы используете его так:
mWebView.setPictureListener(new MyPictureListener());
//... and then later on....
class MyPictureListener implements PictureListener {
@Override
public void onNewPicture(WebView view, Picture arg1) {
// put code here that needs to run when the page has finished loading and
// a new "picture" is on the webview.
}
}
Ответ 2
У меня была такая же проблема, чтобы отклонить мой progressdialog при рендеринге моей веб-страницы. Я решил с onPageStarted.
Надеюсь, это решение поможет вам.
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressBar.dismiss();
}
@Override
public void onPageStarted(WebView view, String url,
android.graphics.Bitmap favicon) {
if (!progressBar.isShowing()) {
progressBar.show();
}
};
Ответ 3
Хм, хорошо, если я создаю свой собственный частный класс, он работает...
private class ViewStoryWebViewClient extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(webView, url);
webView.scrollTo(0, 50);
}
}
Ответ 4
Я получаю то же самое с loadDataWithBaseURL()
. Иногда содержимое не отображается, а contentHeight равно 0. Странно, что щелчок в любом месте веб-представления приведет к отображению содержимого. Кроме того, если вы вызываете zoomIn();zoomOut();
в методе onPageFinished()
, появится страница.
EDIT: проблема с моим кодом заключается в том, что содержимое HTML содержало фиктивное имя window.location = в событии onload, и это приводило к тому, что исходный контент не загружался в произвольное время. Извините, я не думаю, что это связано с тем, что вы видите.
Ответ 5
Я буквально искал ответ в течение последних 6 часов и, наконец, нашел тот, который работает, по крайней мере, для меня, и это простой ответ. Таймер
После того, как ваш OnPageFinished запустил таймер так долго, как вы хотите, в моем случае я делал это в течение 2 секунд. Этого времени будет достаточно для просмотра веб-страницы и загрузки всей страницы.
Убедитесь, что вы запускаете таймер в потоке пользовательского интерфейса, если хотите вызвать метод веб-просмотра
Timer myTimer = new Timer(); //global variable
public void startTimer(TimerTask t){
myTimer.scheduleAtFixedRate(t,2000,2000);
}
....
public void onPageFinished(WebView view, String url) {
TimerTask task = new TimerTask() {
@Override
public void run() {
//stuff to do after page is fully loaded
myTimer.cancel();
}
};
startTimer(task);
}
Кстати, это мой первый ответ на stackoverflow. Надеюсь, это поможет кому-то!