Webview 导致应用程序在启动时立即崩溃

问题描述 投票:0回答:3

我正在尝试创建一个 WebView 应用程序,其行为类似于 Facebook Messenger 聊天气泡,可以使用以下 github 项目覆盖其他应用程序: https://github.com/siddharth2010/Bubbles

我下载了该项目并启动了它,它在默认参数下工作得很好,但是当单击“气泡”时,我希望它显示一个网站而不是当前具有的占位符图像和文本。

以下是我所做的修改:

sample_view.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <WebView android:id="@+id/webView"
        android:layout_height="match_parent"
        android:layout_width="match_parent" />

</RelativeLayout>

MainActivity.java

package com.irunawiki.irunawiki;

import android.app.ProgressDialog;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.irunawiki.bubbles.FloatingBubblePermissions;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        WebView view = (WebView) findViewById(R.id.webView);
        view.getSettings().setJavaScriptEnabled(true);
        view.getSettings().getDomStorageEnabled();
        view.setWebViewClient(new WebViewClient());
        view.loadUrl("https://google.com");

        FloatingBubblePermissions.startPermissionRequest(this);
        View startBubble = findViewById(R.id.start_bubble);
        startBubble.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startService(new Intent(getApplicationContext(), SimpleService.class));
            }
        });
    }
}

AndroidManifest.xml

added these:
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

尝试在虚拟机或实际设备中运行此程序将导致立即崩溃。

奇怪的是,它启动时只是查找

WebView view = (WebView) findViewById(R.id.webView);
未注释,但任何 getSettings、setWebViewClient、loadUrl 都会导致应用程序在启动时立即崩溃。

到底是什么导致了崩溃?我对 Android 开发相当陌生,但在查找了类似问题的 stackoverflow 帖子数小时后,我无法让它工作......

java android android-studio webview android-webview
3个回答
0
投票

我认为你的activity_main布局中没有start_bubble视图。

您应该将按钮添加到您的activity_main中,然后您应该将此行更改为此。

View startBubble = findViewById(R.id.start_bubble);

Button startBubble = findViewById(R.id.start_bubble);


0
投票

事实证明,我试图在不活动的布局中选择一个 webview,这导致了崩溃,解决方法是简单地选择其中包含 webview 的布局


-2
投票

这对于处理 webview 崩溃并从中恢复也非常有用。

终止处理API 终止处理 API 处理 WebView 对象的渲染器进程消失的情况,这可能是因为系统终止渲染器以回收必要的内存,也可能是因为渲染器进程崩溃。通过使用此 API,即使渲染器进程消失,您也可以让您的应用程序继续执行。

https://developer.android.com/develop/ui/views/layout/webapps/managing-webview#termination-handle

public class MyRendererTrackingWebViewClient extends WebViewClient {
private WebView mWebView;

@Override
public boolean onRenderProcessGone(WebView view,
        RenderProcessGoneDetail detail) {
    if (!detail.didCrash()) {
        // Renderer is killed because the system ran out of memory. The app
        // can recover gracefully by creating a new WebView instance in the
        // foreground.
        Log.e("MY_APP_TAG", "System killed the WebView rendering process " +
                "to reclaim memory. Recreating...");

        if (mWebView != null) {
            ViewGroup webViewContainer =
                    (ViewGroup) findViewById(R.id.my_web_view_container);
            webViewContainer.removeView(mWebView);
            mWebView.destroy();
            mWebView = null;
        }

        // By this point, the instance variable "mWebView" is guaranteed to
        // be null, so it's safe to reinitialize it.

        return true; // The app continues executing.
    }

    // Renderer crashes because of an internal error, such as a memory
    // access violation.
    Log.e("MY_APP_TAG", "The WebView rendering process crashed!");

    // In this example, the app itself crashes after detecting that the
    // renderer crashed. If you handle the crash more gracefully and let
    // your app continues executing, you must destroy the current WebView
    // instance, specify logic for how the app continues executing, and
    // return "true" instead.
    return false;
}

}

破坏网页视图

 private void destroyWebview() {
    if (webView != null) {
        Utilities.logThis("MainActivity destroyWebview  DESTROY WebView ... ACTION");
        //ViewGroup webViewContainer = (ViewGroup) findViewById(R.id.webview_container);
        webviewContainer.removeView(webView);
        webView.stopLoading();  // Stop any ongoing loading in case of a crash
        webView.onPause();      // Pause JavaScript execution
        webView.clearHistory(); // Clear WebView history
        webView.clearFormData();
        webView.removeAllViews(); // Remove all child views
        webView.clearCache(true);
        webView.destroy();  // Destroy the WebView
        webView = null; // Set the WebView reference to null
        webViewClient = null;
    }
}

以编程方式重建它

 public void setupWebview() {  

    //webView = (WebView) findViewById(R.id.webview);
    // Create a new WebView instance
    webView = new WebView(this);
    webView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

    // Add the WebView to the container
    webviewContainer.addView(webView);


    Log.d("setupWebview", "Webview created " + webView);

    //Enabling hardware acceleration for WebView can improve performance but may also lead to crashes. You can disable it if it's causing issues:
    webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setDomStorageEnabled(true);
    webView.getSettings().setLoadsImagesAutomatically(true);
    webView.getSettings().setAllowContentAccess(true);
    webView.getSettings().setLoadWithOverviewMode(true);
    //webView.getSettings().setAppCacheEnabled(true);
    //webView.getSettings().setAppCacheMaxSize(1024 * 1024 * 8); // 8MB
    webView.getSettings().setUseWideViewPort(true);

    webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        webView.getSettings().setSafeBrowsingEnabled(false);
    }

    webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);

    //webView.setWebViewClient(new WebViewClient()); //https://stackoverflow.com/questions/48054518/android-app-not-connecting-to-internet-on-emulator

    webView.setRendererPriorityPolicy(WebView.RENDERER_PRIORITY_BOUND, true);
    //webViewClient = new MyRendererTrackingWebViewClient(this, webView);
    webViewClient = new MyWebViewClient();

    webView.setWebViewClient(webViewClient);
   

    CookieManager cookieManager = CookieManager.getInstance();
    cookieManager.setAcceptCookie(false);
    cookieManager.setAcceptThirdPartyCookies( webView, false);
}
© www.soinside.com 2019 - 2024. All rights reserved.