10

I have an activity that displays web pages. On some phones (e.g, Huawei Ascend) , this activity crashes in a way that causes the application to restart, but doesn't cause the usual android error popup for reporting. (Other phones (e.g. Nexus) never crash at all.) It does appear to always crash while a web page is loading, but not at any particular point e.g. sometimes at shoulOverrideUrlLoading, sometimes during onPageStarted or onPageFinished.

I think the WebView is causing this--

08-29 21:08:22.577: A/libc(957): Fatal signal 11 (SIGSEGV) at 0x00000008 (code=1), thread 957

--but I can't work out why.

Here's the activity:

public class WebDisplay extends Activity
{

  private String sentUrl = "";
  public WebView myWebView;
  public ProgressBar spinner;

  @SuppressLint("SetJavaScriptEnabled")
  @Override
  protected void onCreate (Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    Log.d("WEBVIEW", "onCreate");
    getWindow().setBackgroundDrawableResource(R.color.white);

    Bundle extras = getIntent().getExtras(); 
    if (null != extras)
    {
      sentUrl = extras.getString("displayURL");
    }

    setContentView(R.layout.webdisplay);

    myWebView = (WebView) findViewById(R.id.webDisplay);
    spinner = (ProgressBar) findViewById(R.id.webLoading);

    // WebView displays default to showing things in exact pixel size at 100%
    // resolution, meaning it generally opens on a zoomed in portion of the 
    // top left of the web page and refuses to let you zoom out, so we have
    // to force it to display pages a bit more reasonably.
    myWebView.getSettings().setLoadWithOverviewMode(true);
    myWebView.getSettings().setUseWideViewPort(true);
    myWebView.getSettings().setPluginState(WebSettings.PluginState.ON);

    // By default, there is no javascript support or zoom controls, so
    // turn both of those on.
    WebSettings webSettings = myWebView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    webSettings.setSupportZoom(true);
    webSettings.setBuiltInZoomControls(true);
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true);

    // We want links to continue opening inside the app.
    myWebView.setWebViewClient(new WebViewClient() {
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
          Log.d("WEBVIEW", "loadUrl="+url);
          view.loadUrl(url); // open link in the same web view.          
          return true;
      }

      @Override
      public void onPageStarted(WebView view, String url, android.graphics.Bitmap favicon) {
        Log.d("WEBVIEW", "onPageStarted="+url);
        super.onPageStarted(view, url, favicon);
        if (View.GONE == spinner.getVisibility()) { spinner.setVisibility(View.VISIBLE); }
      }

      @Override
      public void onPageFinished(WebView view, String url) {
        Log.d("WEBVIEW", "onPageFinished="+url);
        super.onPageFinished(view, url);
        if (View.VISIBLE == spinner.getVisibility()) { spinner.setVisibility(View.GONE); }
      }

      @Override
      public void onReceivedError(WebView view, int errorCode, String description, String url) {
        Log.d("WEBVIEW", "onPageError="+url+"::descr="+description);
      }

    });

    // Try to get YouTube videos working.
    myWebView.setWebChromeClient(new WebChromeClient() {
    });

    // So the user doesn't have to back through their entire history to get 
    // back to the app, we provide a "done browsing" button.
    Button doneButton = (Button) findViewById(R.id.doneButton);
    doneButton.setOnClickListener(new OnClickListener(){
      @Override
      public void onClick(View v)
      {
        finish();
      }
    });

    ImageButton backButton = (ImageButton) findViewById(R.id.webBackButton);
    backButton.setOnClickListener(new OnClickListener(){
      @Override
      public void onClick(View arg0)
      {
        myWebView.goBack();
      }      
    });

    ImageButton fwdButton = (ImageButton) findViewById(R.id.webForwardButton);
    fwdButton.setOnClickListener(new OnClickListener(){
      @Override
      public void onClick(View arg0)
      {
        myWebView.goForward();
      }      
    });

    ImageButton refreshButton = (ImageButton) findViewById(R.id.refreshButton);
    refreshButton.setOnClickListener(new OnClickListener(){
      @Override
      public void onClick(View arg0)
      {
        myWebView.reload();
      }      
    });

    myWebView.loadUrl(sentUrl);
  }

  @Override
  protected void onSaveInstanceState(Bundle outState)
  {
    super.onSaveInstanceState(outState);

    // Save the state of the WebView
    myWebView.saveState(outState);
  }

  @Override
  protected void onRestoreInstanceState(Bundle savedInstanceState)
  {
    super.onRestoreInstanceState(savedInstanceState);

    // Restore the state of the WebView
    myWebView.restoreState(savedInstanceState);
  }
}

And here's the loaded layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white" >


   <RelativeLayout
        android:id="@+id/webNavBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/abs__background_holo_light"
        android:layout_alignParentBottom="true"
        android:padding="2dp" >

    <Button
        android:id="@+id/doneButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/refreshButton"
        android:layout_alignTop="@+id/refreshButton"
        android:background="@drawable/custom_button"
        android:padding="5dp"
        android:text="@string/web_done"
        android:textColor="@color/white"
        android:textStyle="bold" />

    <ImageButton
        android:id="@+id/refreshButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:background="@drawable/custom_button"
        android:src="@drawable/ic_action_refresh"
        android:contentDescription="@string/web_refresh"
        android:textColor="@color/white" 
        android:padding="5dp" />

     <ImageButton
         android:id="@+id/webBackButton"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentTop="true"
         android:layout_marginRight="5dp"
         android:layout_toLeftOf="@+id/webForwardButton"
         android:background="@drawable/custom_button"
         android:src="@drawable/navigation_back"
         android:padding="5dp"
         android:contentDescription="@string/web_back"
         android:textColor="@color/white" />

    <ImageButton
        android:id="@+id/webForwardButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:background="@drawable/custom_button"
        android:src="@drawable/navigation_forward"
        android:contentDescription="@string/web_forward"
        android:textColor="@color/white" 
        android:padding="5dp" />



     </RelativeLayout>

     <WebView
        android:id="@+id/webDisplay"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:layout_above="@id/webNavBar" />

     <ProgressBar
         android:id="@+id/webLoading"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentTop="true"
         android:layout_marginTop="80dp"
         style="@android:style/Widget.ProgressBar.Large"         
         android:layout_centerHorizontal="true" />

</RelativeLayout>

ETA: Turning hardware acceleration off like this

myWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

seems to stop the SIGSEV thing, but also stops YouTube videos playing (I still have audio, but no image).

Ben Williams
  • 6,027
  • 2
  • 30
  • 54
  • Have you seen these? http://stackoverflow.com/questions/14023291/fatal-signal-11-sigsegv-at-0x00000000-code-1-phonegap http://stackoverflow.com/questions/10662446/invalid-heap-address-and-fatal-signal-11 – Jason Crosby Aug 30 '13 at 17:05
  • 3
    @JasonCrosby - yeah; sadly, the "this is a bug in the firmware of the device" answer seems the most likely to be true (and simultaneously the least helpful when it comes to actually preventing the error; damn you, Android device manufacturers!) – Ben Williams Sep 02 '13 at 09:41
  • Lol yea its always frustrating when there is a bug and you can't do much about it. – Jason Crosby Sep 02 '13 at 14:14
  • Hi, i am facing a similar kind of thing in my device too. When i am opening an https url after a couple of minutes the mainactivity restarts. There is no error that shows up. Did you manage to solve this? How ? Pleas help – Rat-a-tat-a-tat Ratatouille Oct 09 '13 at 10:05
  • 1
    Same problem on a Samsung Galaxy Tab :( – cprcrack Dec 14 '13 at 19:40

2 Answers2

1

make sure the WebView is the first element of the RelativeLayout. or don't use RelativeLayout, just try LinearLayout. or remove the attributes android:layout_alignParentTop="true" android:layout_above="@id/webNavBar" of WebView

cyjss
  • 27
  • 3
0
webSettings.setJavaScriptEnabled(true);

Settings above causes "Fatal signal 11 (SIGSEGV)" error for some sites using java script. I reproduced this error on Samsung Galaxy Tab 3 And Galaxy tab 3 lite. Android version is 4.4.2 for both devices.

If I remove "setJavaScriptEnabled" function, it is working fine.

Anirudh Sharma
  • 7,968
  • 13
  • 40
  • 42