Blame | Last modification | View Log | RSS feed
/*** Copyright 2010-present Facebook.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.facebook;import android.annotation.TargetApi;import android.os.AsyncTask;import android.os.Handler;import android.util.Log;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.net.HttpURLConnection;import java.util.Collection;import java.util.List;import java.util.concurrent.Executor;/*** Defines an AsyncTask suitable for executing a Request in the background. May be subclassed* by applications having unique threading model needs.*/public class RequestAsyncTask extends AsyncTask<Void, Void, List<Response>> {private static final String TAG = RequestAsyncTask.class.getCanonicalName();private static Method executeOnExecutorMethod;private final HttpURLConnection connection;private final RequestBatch requests;private Exception exception;static {for (Method method : AsyncTask.class.getMethods()) {if ("executeOnExecutor".equals(method.getName())) {Class<?>[] parameters = method.getParameterTypes();if ((parameters.length == 2) && (parameters[0] == Executor.class) && parameters[1].isArray()) {executeOnExecutorMethod = method;break;}}}}/*** Constructor. Serialization of the requests will be done in the background, so any serialization-* related errors will be returned via the Response.getException() method.** @param requests the requests to execute*/public RequestAsyncTask(Request... requests) {this(null, new RequestBatch(requests));}/*** Constructor. Serialization of the requests will be done in the background, so any serialization-* related errors will be returned via the Response.getException() method.** @param requests the requests to execute*/public RequestAsyncTask(Collection<Request> requests) {this(null, new RequestBatch(requests));}/*** Constructor. Serialization of the requests will be done in the background, so any serialization-* related errors will be returned via the Response.getException() method.** @param requests the requests to execute*/public RequestAsyncTask(RequestBatch requests) {this(null, requests);}/*** Constructor that allows specification of an HTTP connection to use for executing* the requests. No validation is done that the contents of the connection actually* reflect the serialized requests, so it is the caller's responsibility to ensure* that it will correctly generate the desired responses.** @param connection the HTTP connection to use to execute the requests* @param requests the requests to execute*/public RequestAsyncTask(HttpURLConnection connection, Request... requests) {this(connection, new RequestBatch(requests));}/*** Constructor that allows specification of an HTTP connection to use for executing* the requests. No validation is done that the contents of the connection actually* reflect the serialized requests, so it is the caller's responsibility to ensure* that it will correctly generate the desired responses.** @param connection the HTTP connection to use to execute the requests* @param requests the requests to execute*/public RequestAsyncTask(HttpURLConnection connection, Collection<Request> requests) {this(connection, new RequestBatch(requests));}/*** Constructor that allows specification of an HTTP connection to use for executing* the requests. No validation is done that the contents of the connection actually* reflect the serialized requests, so it is the caller's responsibility to ensure* that it will correctly generate the desired responses.** @param connection the HTTP connection to use to execute the requests* @param requests the requests to execute*/public RequestAsyncTask(HttpURLConnection connection, RequestBatch requests) {this.requests = requests;this.connection = connection;}protected final Exception getException() {return exception;}protected final RequestBatch getRequests() {return requests;}@Overridepublic String toString() {return new StringBuilder().append("{RequestAsyncTask: ").append(" connection: ").append(connection).append(", requests: ").append(requests).append("}").toString();}@Overrideprotected void onPreExecute() {super.onPreExecute();if (requests.getCallbackHandler() == null) {// We want any callbacks to go to a handler on this thread unless a handler has already been specified.requests.setCallbackHandler(new Handler());}}@Overrideprotected void onPostExecute(List<Response> result) {super.onPostExecute(result);if (exception != null) {Log.d(TAG, String.format("onPostExecute: exception encountered during request: %s", exception.getMessage()));}}@Overrideprotected List<Response> doInBackground(Void... params) {try {if (connection == null) {return requests.executeAndWait();} else {return Request.executeConnectionAndWait(connection, requests);}} catch (Exception e) {exception = e;return null;}}RequestAsyncTask executeOnSettingsExecutor() {if (executeOnExecutorMethod != null) {try {executeOnExecutorMethod.invoke(this, Settings.getExecutor(), null);} catch (InvocationTargetException e) {// fall-through} catch (IllegalAccessException e) {// fall-through}} else {this.execute();}return this;}}