I try to print a PDF file and it works fine until I try to print a malformed PDF file.
I don't know why the application crashes even though I used try / catch to prevent crashes. I checked and found out that PrintManager.java:1101 throws RuntimeException:
case MSG_ON_KILL: {
if (DEBUG) {
Log.i(LOG_TAG, "onKill()");
}
String reason = (String) message.obj;
throw new RuntimeException(reason);
}
so code below shouldn't lead to crash:
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();
}
}
Exception that I get after try to print 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)
Why try/catch code doesn't catch this exception? How can I secure this piece of code from crashing?
This happens because some "Genius" Google developer has come up with the "Great" idea of throwing an exception in the main thread causing your application to close. I have tried to solve the problem using reflection but the implementation is too closed. Unfortunately, you have to use it assuming the imminent closure of your application in case of incorrect files, unless you want to implement a library to check the PDF format before calling the API. Google never fails, you always have to mess around with its implementation.
The secondary thread ends up calling this handler.