I am implementing custom document printing using Android’s Print Framework.

Using the Android's documentation link as reference: https://developer.android.com/training/printing/custom-docs

The flow I am using is PrintManager to display the print picker, implementing PrintDocumentAdapter, then creating the PDF inside onWrite() using PrintedPdfDocument by calling startPage(), drawing content on the Canvas, calling finishPage(), and finally writing the document to the ParcelFileDescriptor passed by the framework.

The Android documentation states that if the work inside onWrite() cannot be completed quickly, it may be executed on a worker thread. However, PrintedPdfDocument (and the underlying PdfDocument) is not thread-safe and only allows one page to be open at a time. This becomes problematic in a multithreaded application where page rendering is expensive and consists of layout computation, bitmap generation, text shaping, and other CPU-heavy operations that ideally should be done in parallel.

In my application, multiple background tasks generate data required to draw each page, but every page still requires mandatory calls to startPage() and finishPage(), both of which operate on a non-thread-safe object. This makes it unclear how to correctly integrate parallel rendering logic with the single-threaded requirement of PrintedPdfDocument.

What is the correct threading model for using Android’s Print Framework in this situation? How should background rendering tasks interact with onWrite() safely when PDF generation itself must remain sequential?

4 Replies 4

Why is this a problem? PrintedPdfDocument is only used when printing. So your onWrite will look like:

onWrite(callback) { Thread { val doc = PrintedPdfDocument(context, attribs) //do work callback() }.start() } There's only one thread actually interacting with the PrintedPdfDocument class, so there's no chance of multithreaded issues. Unless you're talking about a situation where people are concurrently editing the data you're drawing to the document, in which case your app should either prevent that or snapshot the data first.

Lets consider an example where I have an operation to print multiple pages, since we can offload to this worker thread how can I do it using multiple worker threads that helps me to work parallely?

This is not significantly different than how you would handle a UI. In Android, the user interface is single-threaded. So, you use multiple threads to do the "heavy lifting", gather all the information needed to render the UI, and then render the UI on the single thread.

where page rendering is expensive

Page rendering is cheap. All you are doing is drawing to a Canvas. Gathering the information to determine what you are going to draw can be expensive. So, do that up front using multiple threads, then do the literal rendering to the Canvas on the single thread.

In our usecase, we wanted to print large documents (1000-2000 pages) containing graphs, images etc.,

As drawing to Canvas on this single thread might take time so what could be the alternative to do this using multiple threads?

Your Reply

By clicking “Post Your Reply”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.