You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中Fragment打印HTML文档的正确实现方案咨询

解决Android Fragment中WebView打印无响应及ANR问题

咱们先从你代码里的核心问题入手——这也是按钮无响应的直接原因:

1. 控件查找时机错误

在onCreateView方法中,你先调用了container.findViewById(R.id.button),但此时还未加载placeholder2.xml布局,container里根本不存在这个按钮控件,导致button变量为null,点击事件自然无法绑定,这就是初始点击按钮没反应的根源。

2. 潜在的ANR与内存泄漏风险

你在doWebViewPrint中新建了独立的WebView,但未正确管理其生命周期;若页面加载耗时较长,还可能阻塞主线程引发ANR。另外,将临时WebView赋值给成员变量却未在Fragment销毁时清理,容易造成内存泄漏。


修正后的完整实现

第一步:修正CalendarFragment代码

public class CalendarFragment extends Fragment {
    private static final String TAG = "CalendarFragment";
    private WebView mLayoutWebView; // 持有布局内的WebView,而非打印临时WebView

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        // 先加载布局,获取根View
        View rootView = inflater.inflate(R.layout.placeholder2, container, false);
        
        // 从根View中查找按钮,而非container
        Button printBtn = rootView.findViewById(R.id.button);
        printBtn.setOnClickListener(v -> triggerWebViewPrint());
        
        // 初始化布局内的WebView并加载目标HTML
        mLayoutWebView = rootView.findViewById(R.id.wv);
        WebSettings webSettings = mLayoutWebView.getSettings();
        webSettings.setJavaScriptEnabled(true); // 若HTML依赖JS则开启
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setUseWideViewPort(true);
        mLayoutWebView.loadUrl("file:///android_asset/calendar.html");
        
        return rootView;
    }

    private void triggerWebViewPrint() {
        if (mLayoutWebView == null) return;
        
        // 监听页面加载状态,确保加载完成后再打印
        mLayoutWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                Log.i(TAG, "页面加载完成,启动打印流程");
                createPrintJob(view);
            }
        });
        
        // 若页面已加载完成,直接触发打印
        if (mLayoutWebView.getProgress() == 100) {
            createPrintJob(mLayoutWebView);
        }
    }

    private void createPrintJob(WebView webView) {
        PrintManager printManager = (PrintManager) requireActivity()
                .getSystemService(Context.PRINT_SERVICE);
        String jobName = getString(R.string.app_name) + " 日历文档";
        
        // 自定义打印属性(可选,比如纸张尺寸、分辨率)
        PrintAttributes printAttrs = new PrintAttributes.Builder()
                .setMediaSize(PrintAttributes.MediaSize.ISO_A4)
                .setResolution(new PrintAttributes.Resolution("custom", Context.PRINT_SERVICE, 300, 300))
                .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
                .build();
        
        PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter(jobName);
        printManager.print(jobName, printAdapter, printAttrs);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        // 清理WebView,避免内存泄漏
        if (mLayoutWebView != null) {
            mLayoutWebView.stopLoading();
            mLayoutWebView.setWebViewClient(null);
            mLayoutWebView.destroy();
            mLayoutWebView = null;
        }
    }
}

第二步:布局无需改动(可按需调整)

你的placeholder2.xml布局结构没问题,若需要适配更多设备,可将RelativeLayout替换为ConstraintLayout优化布局适配。


额外问题说明

  • 关于Cannot find SearchIndexableResources for PrintSettingsFragment日志:这是系统打印服务的内部日志,与你的应用代码无关,无需处理。
  • 关于ANR问题:修正后的代码优化了WebView生命周期管理,避免了主线程阻塞;若仍出现ANR,建议检查你的HTML文档是否包含耗时的JS操作,或尝试拆分复杂页面逻辑。

内容的提问来源于stack exchange,提问作者Max Clifford

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:43:44