Reputation: 101
I have came into a weird scenario of using Android WebView widget:
I have two activities, let's call them A and B. A has a button and a webview. Clicking the button in A will launch B. B has only a webview.
Here is the problem: For certain urls, the "onPageFinished()" method of the WebViewClient (which is set on B) is never called, if Activity A is still on the stack. If I call finish() on A when launching B, the "onPageFinished()" will get called.
So it seems to me that the existence of webview in A has some effect on the other webview in B. Why is that? How can I solve this problem?
This problem only happens on my OS 4.4 devices. For OS 5.x or OS 4.0, the code works perfectly.
Here is my source code:
public class MainActivity extends ActionBarActivity {
private ViewGroup browserContainer;
private WebView browser;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_main);
this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
this.getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.color.background_material_dark));
browserContainer = (ViewGroup) findViewById(R.id.webview_container);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
browser = (WebView) findViewById(R.id.message_view);
browserContainer.setVisibility(View.INVISIBLE);
browser.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
browserContainer.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
}
});
browser.loadUrl("http://www.google.com");
Button nextBtn = (Button)findViewById(R.id.next);
nextBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this, WebviewActivity.class);
startActivity(i);
// uncomment below line will fix the problem
// finish();
}
});
}
@SuppressLint("NewApi")
@Override
public void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= 11) {
browser.onResume();
}
}
@SuppressLint("NewApi")
@Override
public void onPause() {
super.onPause();
if (Build.VERSION.SDK_INT >= 11) {
browser.onPause();
}
}}
public class WebviewActivity extends ActionBarActivity {
private WebView browser;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_webview);
this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
this.getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.color.background_material_dark));
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
browser = (WebView) findViewById(R.id.message_view);
browser.setVisibility(View.INVISIBLE);
browser.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
showMessage();
}
});
if (savedInstanceState == null) {
// below url contains <video> component.
String url = "http://techslides.com/sample-webm-ogg-and-mp4-video-files-for-html5" ;
browser.loadUrl(url);
}
}
@SuppressLint("NewApi")
@Override
public void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= 11) {
browser.onResume();
}
}
@SuppressLint("NewApi")
@Override
public void onPause() {
super.onPause();
if (Build.VERSION.SDK_INT >= 11) {
browser.onPause();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
}
return false;
}
/**
* Reveals the message.
*/
private void showMessage() {
browser.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
}}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/webview_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/next"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="NEXT"/>
<WebView
android:id="@+id/message_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?android:progressBarStyleLarge"
android:layout_gravity="center"/>
</FrameLayout>
activity_webview.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/message_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?android:progressBarStyleLarge"
android:layout_gravity="center"/>
</FrameLayout>
Upvotes: 2
Views: 1547
Reputation: 101
It turns out that the HTML content retrieved by my webview in B activity has a video tag. Problem is that if this video tag does not have "preload" or "poster" attribute, then onPageFinished() method is never called. This bug is reported here. To fix the problem, modify the HTML content to add "preload=none" or "poster". For me, because I don't own the content, I have to download the content programmatically, add the "preload=none", and then feed the content to my webview. This is a hack, but it's the best I can think of now.
Upvotes: 3