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?