【问题标题】:Malformed PDF print doesn't catch RuntimeException格式错误的 PDF 打印不会捕获 RuntimeException
【发布时间】:2020-06-15 22:29:15
【问题描述】:

我尝试打印 PDF 文件,但在我尝试打印格式错误的 PDF 文件之前它工作正常。 即使我使用try / catch 来防止崩溃,我也不知道为什么应用程序会崩溃。我查了一下发现PrintManager.java:1101会抛出RuntimeException

 case MSG_ON_KILL: {
     if (DEBUG) {
         Log.i(LOG_TAG, "onKill()");
     }

     String reason = (String) message.obj;
     throw new RuntimeException(reason);
 }

所以下面的代码不应该导致崩溃:

public static void startPdfPrintProcedure(@NonNull Context context, @NonNull String filePath, @Nullable String jobName) {
    try {
        PrintManager printManager = (PrintManager) context.getSystemService(Context.PRINT_SERVICE);
        String jobName = formatDefaultJobName(context.getResources(), jobName);
        PrintDocumentAdapter pda = new SimplePrintDocumentAdapter(new File(filePath));
        if (printManager != null) {
            try {
                printManager.print(jobName, pda, null); // <- crash here even though there is a try/catch
            } catch (RuntimeException e) {
                showUnknownError();
            }
        } else {
            showUnknownError();
        }
    } catch (RuntimeException e) {
        showUnknownError();
    }
}

尝试打印 PDF 后遇到的异常。 :

 java.lang.RuntimeException: Cannot print a malformed PDF file
    at android.print.PrintManager$PrintDocumentAdapterDelegate$MyHandler.handleMessage(PrintManager.java:1101)
    at android.os.Handler.dispatchMessage(Handler.java:112)
    at android.os.Looper.loop(Looper.java:216)
    at android.app.ActivityThread.main(ActivityThread.java:7625)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

为什么try/catch 代码没有捕捉到这个异常?如何确保这段代码不会崩溃?

【问题讨论】:

  • 我认为这些捕获没有理由不排除异常。将System.out 首先放在两个捕获中,看看它们是否打印了一些东西。或者使用调试器并在 2 个捕获中放置一个断点
  • @Bentaye 我放了日志,但两个捕获都不起作用。但令人惊讶的是,日志显示在printManager.print(...)之前和之后
  • 所以该行没有抛出任何 RuntimeException。您在堆栈跟踪中能看到多远?为什么你认为printManager.print(...) 是抛出异常的那一行?
  • @Bentaye 你是对的。我认为崩溃发生在printManager.print(...) 行,但我在调用try/catch 块后检查并编码。然后出现打印对话框,应用程序崩溃。

标签: java android android-print-manager


【解决方案1】:

发生这种情况是因为某些“天才”Google 开发人员提出了在主线程中引发异常导致您的应用程序关闭的“好”想法。 我曾尝试使用反射来解决问题,但实现过于封闭。 不幸的是,如果文件不正确,您必须假设您的应用程序即将关闭,除非您想在调用 API 之前实现一个库来检查 PDF 格式,否则您必须使用它。 Google 永远不会失败,你总是不得不在它的实现上搞砸。

辅助线程最终调用此处理程序。

    private final class MyHandler extends Handler {

            public static final int MSG_ON_KILL = 5;
            ...

            @Override
            public void handleMessage(Message message) {
                switch (message.what) {
                    ...
                    
                    case MSG_ON_KILL: {
                        if (DEBUG) {
                            Log.i(LOG_TAG, "onKill()");
                        }

                        String reason = (String) message.obj;
                        throw new RuntimeException(reason);<---------
                    }

                    default: {
                        throw new IllegalArgumentException("Unknown message: "
                                + message.what);
                    }
                }
            }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 2021-05-31
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多