studio programacion móviles español desarrollo curso componentes arquitectura aplicaciones java android multithreading architecture

java - móviles - manual de programacion android pdf



Componentes de la arquitectura de Android hilos de la red (1)

Parece que tienes algunos conceptos erróneos.

En general, nunca está bien llamar a la red desde el subproceso principal (UI), pero a menos que tenga muchos datos, podría estar bien recuperar los datos de la base de datos en el subproceso principal. Y esto es lo que hace el ejemplo de Google.

1.

La demostración utiliza el marco de los ejecutores y define un grupo fijo con 3 subprocesos para networkIO, sin embargo, en la demostración solo se define una tarea de trabajo para una llamada, es decir, la FetchNextSearchPageTask.

En primer lugar, desde Java 8 puede crear una implementación simple de algunas interfaces (llamadas "interfaces funcionales") usando la sintaxis lambda. Esto es lo que sucede en el NetworkBoundResource :

appExecutors.diskIO().execute(() -> { saveCallResult(processResponse(response)); appExecutors.mainThread().execute(() -> // we specially request a new live data, // otherwise we will get immediately last cached value, // which may not be updated with latest results received from network. result.addSource(loadFromDb(), newData -> result.setValue(Resource.success(newData))) ); });

en la primera tarea ( saveCallResult y saveCallResult ) se programa en un subproceso proporcionado por el diskIO Executor y luego desde ese subproceso, el resto del trabajo se programa de nuevo en el subproceso principal.

2.

¿Por qué se aplica @MainThread aquí para networkIO?

y

Todas las demás solicitudes de red parecen ejecutarse en el hilo principal.

Esto no es así. Solo el envoltorio de resultados, es decir, LiveData<ApiResponse<RequestType>> se crea en el hilo principal. La solicitud de red se realiza en un hilo diferente. Esto no es fácil de ver porque la biblioteca Retrofit se utiliza para hacer todo el trabajo pesado relacionado con la red y oculta muy bien esos detalles de implementación. Sin embargo, si observa el LiveDataCallAdapter que envuelve la LiveDataCallAdapter en un LiveData , puede ver que se utiliza Call.enqueue que en realidad es una llamada asíncrona (programada internamente por Retrofit).

En realidad, si no fuera por la función de "paginación", el ejemplo no necesitaría en networkIO Executor networkIO . "Paginación" es una característica complicada y, por lo tanto, se implementa mediante el uso explícito de FetchNextSearchPageTask y este es un lugar donde creo que el ejemplo de Google no se realiza muy bien: FetchNextSearchPageTask no reutiliza la lógica de análisis de solicitudes (es decir, processResponse ) de RepoRepository pero solo asume que es trivial (como lo es ahora, pero quién sabe sobre el futuro ...). Además, no hay una programación del trabajo de fusión en el diskIO Executor que también es incompatible con el resto del procesamiento de la respuesta.

Actualmente estoy revisando la siguiente guía: https://developer.android.com/topic/libraries/architecture/guide.html

La clase networkBoundResource:

// ResultType: Type for the Resource data // RequestType: Type for the API response public abstract class NetworkBoundResource<ResultType, RequestType> { // Called to save the result of the API response into the database @WorkerThread protected abstract void saveCallResult(@NonNull RequestType item); // Called with the data in the database to decide whether it should be // fetched from the network. @MainThread protected abstract boolean shouldFetch(@Nullable ResultType data); // Called to get the cached data from the database @NonNull @MainThread protected abstract LiveData<ResultType> loadFromDb(); // Called to create the API call. @NonNull @MainThread protected abstract LiveData<ApiResponse<RequestType>> createCall(); // Called when the fetch fails. The child class may want to reset components // like rate limiter. @MainThread protected void onFetchFailed() { } // returns a LiveData that represents the resource public final LiveData<Resource<ResultType>> getAsLiveData() { return result; } }

Estoy un poco confundido aquí sobre el uso de hilos.
¿Por qué se aplica @MainThread aquí para networkIO?
Además, para guardar en la base de datos, se aplica @WorkerThread, mientras que @MainThread para recuperar resultados.

¿Es una mala práctica usar un subproceso de trabajo por defecto para NetworkIO y la interacción de db local?

También estoy revisando la siguiente demostración (GithubBrowserSample): https://github.com/googlesamples/android-architecture-components
Esto me confunde desde un punto de vista de hilos.
La demostración utiliza el marco de los ejecutores y define un grupo fijo con 3 subprocesos para networkIO, sin embargo, en la demostración solo se define una tarea de trabajo para una llamada, es decir, la FetchNextSearchPageTask . Todas las demás solicitudes de red parecen ejecutarse en el hilo principal.

¿Alguien puede aclarar la razón?