La travesía para construir clientes
Los primeros serán los últimos
request
response
OnPreExecute()
OnPostExecute()
doInBackground()
public class AsyncTaskRequest extends AsyncTask<String, Void, ArrayList<Artist>> {
private AsyncResponse responseListener;
public AsyncTaskRequest(@NonNull AsyncResponse responseListener) {
this.responseListener = responseListener;
}
@Override
protected Object doInBackground(String... params) {
if (params.length == 0) {
responseListener.onError();
return null;
}
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String artistQuery = params[0];
String response;
Uri uri = new Uri.Builder()
.scheme("https")
.authority("api.spotify.com")
.appendPath("/v1")
.appendPath("/search")
.appendQueryParameter("type","artist")
.appendQueryParameter("q",artistQuery)
.build();
try {
//Apertura de conexión
URL url = new URL(uri.toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
//Obtener el stream de respuesta
InputStream inputStream = urlConnection.getInputStream();
StringBuilder buffer = new StringBuilder();
if (inputStream == null) {
responseListener.onError();
return null;
}
//Acceso de lectura al stream de respuesta
reader = new BufferedReader(new InputStreamReader(inputStream));
//Construcción de la respuesta en un string
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line)
.append("\n");
}
if (buffer.length() == 0) {
responseListener.onError();
return null;
}
response = buffer.toString();
}catch (IOException e){
responseListener.onError();
return null;
}catch (MalformedURLException e) {
e.printStackTrace();
}finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
responseListener.onError();
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
try{
return parseResponse(response);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(ArrayList<Artist> artists) {
super.onPostExecute(responseObject);
responseListener.onResponse(responseObject);
}
public interface AsyncResponse {
public void onResponse(ArrayList<Artist> artists);
public void onError();
}
}Compacto para su conveniencia
Importar la librería en el Gradle y añadir permisos
Crear un Singleton
Añade tus peticiones
The Big Picture
Añadir Request al RequestQueue
Ejecutar el Request de manera asíncrona
Devolver la respuesta al hilo principal
public class VolleyClient extends Application{
public static final String TAG = VolleyClient.class
.getSimpleName();
private static VolleyClient mInstance;
private RequestQueue mRequestQueue;
private static Context mCtx;
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
private VolleyClient(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
}
public static synchronized VolleyClient getInstance(Context context) {
if (mInstance == null) {
mInstance = new VolleyClient(context);
}
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
// set the default tag if tag is empty
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Manejo de la respuesta
parseArtistsResponse(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// Manejo de errores
error.printStackTrace();
}
});
// Añadir la petición a la cola de peticiones
Volley.newRequestQueue(this).add(stringRequest);The android rest client
ApiClient.Java
ApiService.Java
models
public interface SpotifyApiService {
@GET("/v1/search?type=artist")
void searchArtist(@Query("q") String query,
Callback<ArtistSearchResponse> serverResponse);
} @GET("/v1/search?type=artist")
@GET("/{version}/search?type=artist")Las anotaciones de los métodos, de primera instancia, nos permiten manipular el tipo de método y la URL a la cuál haremos la petición.
Los argumentos que contenga el método de la petición definen por medio de anotaciones qué papel jugará ese argumento.
@GET("/v1/search?type=artist")
void searchArtist(@Query("q") String query,
Callback<ArtistSearchResponse> serverResponse);
searchArtist("just", this);
/v1/search?type=artist&q=justAPP
Client
Server
public class ApiClient {
public static ApiClient API_CLIENT;
public static ApiClient getInstance(Context context) {
if(API_CLIENT == null)
API_CLIENT = new ApiClient()
return API_CLIENT
}
private ApiClient (Context context){
//Constructor
}
}@GET("/v1/search?type=artist")
Observable<ArtistSearchResponse> searchArtist(@Query("q") String query);public void performSearch(String query) {
apiService.searchArtist(query)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<ArtistSearchResponse>() {
@Override
public void call(ArtistSearchResponse artistSearchResponse) {
artistSearchResponse.getArtists();
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
throwable.printStackTrace();
}
});
}@GET("/v1/search?type=artist")
Observable<ArtistSearchResponse> searchArtist(@Query("q") String query);public void performSearch(String query) {
apiService.searchArtist(query)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
ArtistSearchResponse::getArtists,
Throwable::printStackTrace);
}apiService.searchArtist(query)
.observeOn(AndroidSchedulers.mainThread())
.flatMap(artistSearchResponse -> Observable.from(artistSearchResponse.getArtists()))
.first()
.subscribe(Artist::getName);apiService.searchArtist(query)
.observeOn(AndroidSchedulers.mainThread())
.flatMap(artistSearchResponse -> Observable.from(artistSearchResponse.getArtists()))
.last()
.subscribe(Artist::getName);@GET("/v1/artist")
Observable<Bio> getBio(@Query("name") String artistName);apiService.searchArtist(query)
.observeOn(AndroidSchedulers.mainThread())
.flatMap(artistSearchResponse -> Observable.from(artistSearchResponse.getArtists()))
.flatMap(artist -> apiService.getArtistBio(artist.getName()))
.subscribe(bio -> bio.getAutor());getApiService().downloadPDFHeader()
.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.newThread())
.concatMap(response -> {
readContentLength(response);
setupFile();
writeInCache(response);
return Observable.from(obtainBlocks());
})
.concatMap(offset1 -> {
int end;
if (offset1 + BLOCK_SIZE > (contentLength - 1))
end = (int)contentLength;
else
end = offset1 + BLOCK_SIZE;
String range = getResources().getString(R.string.range_format, offset1, end);
return ApiAdapter.getApiService().downloadPDFBlock(range);
})
.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.newThread())
.subscribe(this::writeInCache);silmood
@silmood