我正在尝试创建一个 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 帖子数小时后,我无法让它工作......
我认为你的activity_main布局中没有start_bubble视图。
您应该将按钮添加到您的activity_main中,然后您应该将此行更改为此。
View startBubble = findViewById(R.id.start_bubble);
Button startBubble = findViewById(R.id.start_bubble);
事实证明,我试图在不活动的布局中选择一个 webview,这导致了崩溃,解决方法是简单地选择其中包含 webview 的布局
这对于处理 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);
}