Sending a simple Query

Send a Query

At a high level, you use Content API by creating a single ContentManager instance for the application and passing it Query objects. The ContentManager manages worker threads for running the network operations, reading from and writing to the cache, and parsing responses. Queries do the parsing of raw responses and ContentManager takes care of dispatching the parsed response back to the main thread for delivery.

This lesson describes how to send a request using the ContentManager.postQuery() convenience method. This lesson also describes how to add a query to the ContentManager queue and cancel a query.

Set up ContentManager

To post a query, you simply construct one and add it to the ContentManager queue with postQuery(), as shown above. Once you add the query it moves through the pipeline, gets serviced, and has its response parsed and delivered.

// Instantiate the ContentManager.
ContentManager manager = new ContentManager();
manager.start();

Create a Query

String url ="http://www.neomades.com";

// Request a response from the provided URL.
ContentQuery query = new ContentQuery(Method.GET, url);
query.setResponseParser(new Parser() {
        public Object deserialize(byte[] data) {
                return new String(data);
        }
});
// used for event type
query.setContentResponseType("neomadesCom");

Post query to the queue

Content API provides a convenience method ContentManager.postQuery that sets up a queue of queries for you, using default values, and starts the queue.

When you call postQuery(), ContentManager runs one cache processing thread and a pool of network dispatch threads. When you add a query to the queue, it is picked up by the cache thread: if the query can be serviced from cache, the cached response is parsed on the cache thread and the parsed response is delivered on the main thread. If the request cannot be serviced from cache, it is placed on the network queue. The first available network thread takes the request from the queue, performs the HTTP transaction, parses the response on the worker thread, writes the response to cache, and posts the parsed response back to the main thread for delivery.

// Add the query to the manager.
manager.postContentQuery(query);

Lifecycle of a query

Content Network Cache

Handle the query response

ContentManager always delivers ContentResponse responses on the main thread through the Screen.onContentResponse() method. Running on the main thread is convenient for populating UI controls with received data, as you can freely modify UI controls directly from your response handler, but it’s especially critical to many of the important semantics provided by the library, particularly related to canceling queries.

Note that expensive operations like blocking I/O and parsing/decoding are done on worker threads. You can add a request from any thread, but responses are always delivered on the main thread.

@Override
public void onContentResponse(ContentResponse response) {
        // event that corresponds to neomades.com query
        if (response.hasType("neomadesCom")) {
                String responseString = (String)response.getValue();
                textLabel.setText("Response is: "+ responseString);
        }
}

Handle the query error

@Override
public void onContentError(ContentResponse response) {
        textLabel.setText("That didn't work!");
}

Cancel a ContentQuery

To cancel a request, call cancel() on your Request object. Once cancelled, Content API guarantees that your response handler will never be called. What this means in practice is that you can cancel all of your pending queries in your screen’s onDestroy() method.

To take advantage of this behavior, you would typically have to track all in-flight queries in order to be able to cancel them at the appropriate time. There is an easier way: you can associate a tag object with each request. You can then use this tag to provide a scope of queries to cancel.

For example, you can tag all of your queries with the Screen they are being made on behalf of, and call manager.cancelAll(your tag) from onDestroy(). Here is an example that uses a string value for the tag:

Define your tag and add it to your queries.

// ...
public static final String TAG = "MyTag";
ContentQuery stringQuery; // Assume this exists.
ContentManager manager;  // Assume this exists.

// Set the tag on the query.
stringQuery.setTag(TAG);

// Add the request to the RequestQueue.
manager.postContentQuery(stringQuery);

In your screen’s onDestroy() method, cancel all queries that have this tag.

@Override
protected void onDestroy() {
    super.onDestroy();
    postQuery(new CancelQuery(TAG));
}

Take care when canceling queries. If you are depending on your response handler to advance a state or kick off another process, you need to account for this. Again, the response handler will not be called.