Android应用WebView点击_blank链接无法显示新WebView的问题求助
Android WebView点击
target="_blank"链接创建的新WebView不显示内容(日志正常输出) 问题描述
我开发了一款加载adcpc.funwithpasswords.com站点的Android应用,需求是当点击网页中带有target="_blank"属性的链接(比如<a href="https://www.google.com" target="_blank">Go to Google</a>)时,创建一个新的小型WebView并加载目标站点。但实际操作时,Logcat能正常输出Opening URL: https://www.google.com/和Loaded URL: https://www.google.com/的日志,却看不到新WebView的任何内容。
原MainActivity.java代码
package com.flamenzaapps.adbits; import android.graphics.Color; import android.os.Bundle; import android.util.Log; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.LinearLayout; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { WebView mainWebView; LinearLayout layout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize main WebView mainWebView = findViewById(R.id.webview); layout = findViewById(R.id.layout); // Enable JavaScript for main WebView WebSettings mainWebSettings = mainWebView.getSettings(); mainWebSettings.setJavaScriptEnabled(true); mainWebView.setWebViewClient(new WebViewClient()); mainWebView.loadUrl("https://www.adcpc.funwithpasswords.com"); // Set up a WebViewClient with URL loading handler mainWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { // When a link is clicked, open it in a new smaller WebView openNewWebView(url); return true; // Prevent the default browser to open the link } }); } // Function to create and display a new smaller WebView on the same page private void openNewWebView(String url) { // Log the URL for debugging Log.d("WebView", "Opening URL: " + url); // Create a new WebView WebView newWebView = new WebView(this); // Set up WebSettings for the new WebView WebSettings webSettings = newWebView.getSettings(); webSettings.setJavaScriptEnabled(true); // Enable JavaScript newWebView.setWebViewClient(new WebViewClient() { @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { Log.e("WebView", "Error loading URL: " + description); } }); // Load the clicked URL in the new WebView newWebView.loadUrl(url); // Set layout parameters for the new WebView (make it smaller and position it) LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, 600 // Fixed height for the smaller WebView ); params.topMargin = 20; // Optional: Add margin or positioning logic if needed newWebView.setLayoutParams(params); // Optionally set a background color for debugging visibility newWebView.setBackgroundColor(Color.parseColor("#000000")); // Ensure the parent layout is properly initialized LinearLayout layout = findViewById(R.id.layout); // Make sure this ID is correct if (layout != null) { // Add the new WebView to the layout on the main UI thread runOnUiThread(new Runnable() { @Override public void run() { layout.addView(newWebView); Log.d("WebView", "Loaded URL: " + url); } }); } else { Log.e("WebView", "Layout not found. Make sure layout is initialized."); } } }
解决方案
核心问题分析
WebView对带有target="_blank"的链接,默认会通过WebChromeClient的createWindow方法请求创建新窗口,而不是触发WebViewClient的shouldOverrideUrlLoading。原代码只处理了普通链接的跳转,没处理_blank链接的新窗口请求,导致逻辑不生效。另外还有布局和WebView配置的小问题需要优化。
修复步骤及代码
- 添加WebChromeClient处理
_blank链接的新窗口请求 - 优化WebView配置,确保内容可见
- 避免重复查找布局控件
修复后的完整代码:
package com.flamenzaapps.adbits; import android.graphics.Color; import android.os.Bundle; import android.util.Log; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.webkit.WebChromeClient; import android.widget.LinearLayout; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { WebView mainWebView; LinearLayout layout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize main WebView and layout mainWebView = findViewById(R.id.webview); layout = findViewById(R.id.layout); // Configure main WebView settings WebSettings mainWebSettings = mainWebView.getSettings(); mainWebSettings.setJavaScriptEnabled(true); // 允许WebView支持多窗口(处理_blank链接) mainWebSettings.setSupportMultipleWindows(true); // 设置WebViewClient处理普通链接跳转 mainWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { openNewWebView(url); return true; } }); // 设置WebChromeClient处理_blank链接的新窗口请求 mainWebView.setWebChromeClient(new WebChromeClient() { @Override public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, android.os.Message resultMsg) { // 创建新WebView并加载目标URL WebView newWebView = new WebView(MainActivity.this); // 配置新WebView的settings WebSettings webSettings = newWebView.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setSupportMultipleWindows(true); // 设置WebViewClient处理页面错误和跳转 newWebView.setWebViewClient(new WebViewClient() { @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { Log.e("WebView", "Error loading URL: " + description); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } }); // 传递新WebView的结果消息 WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; transport.setWebView(newWebView); resultMsg.sendToTarget(); // 将新WebView添加到布局 openNewWebViewLayout(newWebView); return true; } }); // 加载初始页面 mainWebView.loadUrl("https://www.adcpc.funwithpasswords.com"); } // 处理普通链接的新WebView创建 private void openNewWebView(String url) { WebView newWebView = new WebView(this); WebSettings webSettings = newWebView.getSettings(); webSettings.setJavaScriptEnabled(true); newWebView.setWebViewClient(new WebViewClient() { @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { Log.e("WebView", "Error loading URL: " + description); } }); newWebView.loadUrl(url); openNewWebViewLayout(newWebView); } // 统一处理新WebView的布局添加 private void openNewWebViewLayout(WebView webView) { Log.d("WebView", "Adding new WebView to layout"); // 设置布局参数 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, 600 ); params.topMargin = 20; webView.setLayoutParams(params); // 设置背景色确保可见(可根据需求调整) webView.setBackgroundColor(Color.parseColor("#FFFFFF")); // 开启硬件加速避免渲染问题 webView.setLayerType(WebView.LAYER_TYPE_HARDWARE, null); // 添加到布局(已在主线程,无需额外调用runOnUiThread) if (layout != null) { layout.addView(webView); Log.d("WebView", "New WebView added successfully"); } else { Log.e("WebView", "Layout reference is null"); } } }
关键修改说明
setSupportMultipleWindows(true):开启WebView的多窗口支持,这是处理_blank链接的前提WebChromeClient.onCreateWindow:专门处理新窗口请求,创建并配置新WebView,同时传递结果消息给系统- 统一布局添加逻辑:把新WebView的布局配置和添加抽成单独方法,避免重复代码
- 开启硬件加速:解决部分设备上WebView内容不渲染的问题
- 移除重复的
findViewById:直接使用成员变量layout,避免空指针风险
内容的提问来源于stack exchange,提问作者M.Riyan
相关产品推荐
相关产品推荐

