0

I am implementing a library function that performs a query on the database and this query can sometime be long enough to cause a StrictMode warning for a long operation on the UI thread.

I was wondering what would it be the right pattern to apply here? How can I wrap an asynchronous call in a function which result is expected to be synchronous?

The function gets a table name and column and returns a boolean using the normal Cursor / resolver.query pattern functionalities. I can add the code if needed.

Thanks a lot, Andrea

1 Answers1

2

You can do anything from a simple Runnable executed by a new Thread to an AsyncTask. An AsyncTask is the "Android way"; otherwise you need to create a Handler so the Runnable (or Thread.run()) can report the results back on the UI thread. The docs for AsyncTask have a lot of details on usage and the API guide topic Processes and Threads has more information.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • An AsyncTask wouldn't be feasible because the main method would just exit without waiting for the AsyncTask to complete. I am thinking `boolean runIfTrue(Runnable callback) { new AsyncTask() { (...) onPostExecute { if(result == true) { // run Runnable callback } } } }` – Andrea Della Corte Oct 01 '13 at 23:41
  • (Comment can't be edited anymore) I would then execute the asynctask and it would in turn run the callback in the postExecute. – Andrea Della Corte Oct 01 '13 at 23:48
  • @AndreaDellaCorte - You need to split up your "main method" so that the part that follows obtaining the result from the data base is executed in the `onPostExecute` method of the `AsyncTask` (or in a method called by `onPostExecute`). – Ted Hopp Oct 02 '13 at 01:18
  • Hi Ted, my function will be used by other teams and I'd like to make the `Asynctask` involvement transparent to them. Otherwise, every time this function needs to be called, they'll have to make the request in an `AsyncTask` and then add their result-dependent code in the `onPostExecute`. – Andrea Della Corte Oct 03 '13 at 14:20
  • @AndreaDellaCorte - It's logically impossible to have a function that does not block yet does not return until the calculation is complete. You need to redesign the API that your teams will be using so that it is based on the reality that that the calculations happen asynchronously. I suggest specifying that the function that initiates the calculations take, as a call parameter, a call-back `Runnable` (or other interface, if appropriate) that will be executed when the results are available. They the teams won't have to know about an `AsyncTask`, but will know about the asynchronicity. – Ted Hopp Oct 03 '13 at 14:34
  • @AndreaDellaCorte - It will be good. By implementing the functionality with a call-back interface, the client code (that the other teams are writing) does not have to worry about `AsyncTask`, threads, or blocking the UI. Those details will be hidden from them inside your function. They will, however, need to organize their code around the expectation that the results won't be available immediately when the function returns, but rather only when the call-back is executed some time later. This is a very common API structure that should be familiar to anyone writing interactive systems. – Ted Hopp Oct 03 '13 at 16:33
  • Hi Ted, in my previous comment I meant to write this `boolean runIfTrue(Runnable callback)` (please see my first comment). Thanks a lot for your help!! – Andrea Della Corte Oct 03 '13 at 17:48
  • @AndreaDellaCorte - That looks more or less like the right structure. What would the boolean return value indicate? That the `AsyncTask` was successfully started? – Ted Hopp Oct 03 '13 at 17:52