Android原生Activity加载Next.js网页出现空白屏问题求助
Android WebView加载Next.js网页空白,但可正常加载主流站点的问题排查
问题描述
- Android原生Activity中的WebView可正常显示Facebook、亚马逊、YouTube等站点,但加载公司自研的Next.js网页时仅显示空白屏
- 已排除证书问题,网页拥有有效安全证书
- 加载过程无错误日志输出,问题在Android 7.1.1至13的所有版本、模拟器和真机上均复现
提供的代码
1. Activity代码
import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.webkit.JavascriptInterface; import android.webkit.ValueCallback; import android.webkit.WebResourceError; import android.webkit.WebResourceRequest; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Button; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; public class OutgoingCallActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); getSupportActionBar().hide(); setContentView(R.layout.activity_outgoing_call); Button button = (Button) findViewById(R.id.button); WebView webView = (WebView) findViewById(R.id.web); webView.getSettings().setJavaScriptEnabled(true); webView.setWebContentsDebuggingEnabled(true); webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); webView.setWebViewClient(new WebViewClient() { @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { Log.e("WEBVIEW_ERROR", error.toString()); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); Log.d("WEBVIEW", "onPageFinished: " + url); view.evaluateJavascript( "(function() { return document.body.innerHTML; })();", new ValueCallback<String>() { @Override public void onReceiveValue(String html) { Log.d("HTML", html); } }); } }); webView.loadUrl("https://www.amazon.com/"); webView.addJavascriptInterface(new WebAppInterface(this), "Android"); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String number = "123456"; Uri call = Uri.parse("tel:" + number); Intent surf = new Intent(Intent.ACTION_CALL, call); startActivity(surf); Log.d("OutgoingCallActivity", "Button Pressed"); } }); } } class WebAppInterface { Context mContext; WebAppInterface(Context c) { mContext = c; } @JavascriptInterface public void sendMessageToApp(String deeplink) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(deeplink)); mContext.startActivity(intent); } }
2. 布局代码
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:background="@color/white" android:fitsSystemWindows="true" android:orientation="vertical" tools:context=".OutgoingCallActivity"> <WebView android:id="@+id/web" android:layout_width="match_parent" android:layout_height="700dp" tools:layout_editor_absoluteX="8dp" tools:layout_editor_absoluteY="8dp" /> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:textColor="#5bc500" android:background="@color/white" android:text="Resume Call" /> </LinearLayout>
补充说明
- 目标网页基于Next.js开发
- WebAppInterface仅用于网页端按钮触发时向APP传递deeplink
- 因公司隐私,无法提供网页URL
排查方向与解决方案建议
原生WebView配置检查
- 启用必要的WebSettings:Next.js依赖现代JS特性,当前仅开启了JavaScriptEnabled,需补充配置:
webView.getSettings().setDomStorageEnabled(true); // 启用DOM存储,Next.js路由和状态依赖 webView.getSettings().setAllowFileAccess(true); webView.getSettings().setLoadWithOverviewMode(true); webView.getSettings().setUseWideViewPort(true); webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); // 针对Android 7.0及以下版本,可尝试开启混合内容支持(若网页存在兼容资源) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { webView.getSettings().setMixedContentMode(android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); } - 移除强制软件渲染设置:
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)可能干扰Next.js的CSS动画、虚拟DOM渲染,建议注释或删除该行 - 添加WebChromeClient捕获JS日志:WebViewClient仅处理页面请求,WebChromeClient可捕获网页控制台日志,帮助定位JS执行异常:
webView.setWebChromeClient(new android.webkit.WebChromeClient() { @Override public boolean onConsoleMessage(android.webkit.ConsoleMessage consoleMessage) { Log.d("WEB_JS_LOG", consoleMessage.message() + " -- 行号: " + consoleMessage.lineNumber() + " 来源: " + consoleMessage.sourceId()); return super.onConsoleMessage(consoleMessage); } }); - 检查页面加载后的DOM内容:通过现有
evaluateJavascript的日志,若返回仅Next.js根节点(<div id="__next"></div>),说明网页JS未执行或执行失败
网页端Next.js配置检查
- 适配旧版浏览器内核:Android WebView内核对应Chrome版本(如Android 7.1对应Chrome 51),需在
next.config.js中配置兼容:module.exports = { browserslist: [ 'Android >= 7', 'Chrome >= 51' ] } - 检查User-Agent限制:部分Next.js站点会限制非桌面UA的访问,可给WebView设置桌面UA测试:
webView.getSettings().setUserAgentString("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"); - 排查CSP内容安全策略:若网页设置了严格的CSP,可能阻止WebView加载资源,需确认CSP规则是否兼容Android WebView环境
其他排查手段
- 使用WebView调试工具:已开启
webContentsDebuggingEnabled,可通过Chrome浏览器的chrome://inspect连接设备,直接查看网页的控制台日志、DOM结构、网络请求,这是最直接的排查方式 - 测试静态页面:若Next.js站点有静态页面,先加载静态页面测试是否正常,排除路由或SSR渲染的问题
内容的提问来源于stack exchange,提问作者Lucas Acuña
相关产品推荐
相关产品推荐

