Aquí hay una solución alternativa para todos los métodos de devolución de llamada, que pueden estar todos sujetos al mismo comportamiento de orden de evento indefinido con ciclo de actividad. A menos que vaya a inspeccionar todo el código de Android para cada devolución de llamada que usa para determinar el desencadenante de origen y quién controla las implementaciones y espera que la base de código no cambie en el futuro, ¿puede decirse realmente que el orden de eventos entre retrollamadas? y los eventos del ciclo de vida de la actividad podrían estar garantizados.
En este momento, estas interacciones de orden normalmente se pueden denominar comportamientos indefinidos, con fines de desarrollo.
Lo mejor sería manejar correctamente este comportamiento indefinido, de manera que nunca será un problema en primer lugar, asegúrate de que las órdenes sean un comportamiento definido.
Mi Sony Xperia, por ejemplo, mientras duerme, hace un ciclo de mi aplicación actual, destruyendo la aplicación y luego reiniciando y poniéndola en estado de pausa, créalo o no.
Cuántas pruebas de comportamiento de ordenación de eventos proporciona Google en su SDK como construcción de prueba especial para implementos de entorno host No lo sé, pero definitivamente es necesario hacer un esfuerzo para garantizar que los comportamientos de las órdenes de eventos estén bloqueados por ser bastante estricto al respecto.
https://code.google.com/p/android/issues/detail?id=214171&sort=-opened&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened
importación android.util.Log; import android.util.SparseArray;
/** * Creado por woliver en 2016/06/24. * * entorno de host Android, dicta un Ciclo de vida de la actividad para OnCreate, onStart, onResume, onPause, onStop, onDestory, * donde estamos obligados a liberar memoria y maneja para que otras aplicaciones utilicen. * Cuando se reanuda, a veces se nos solicita volver a vincular y activar estos elementos con otros objetos. * Normalmente, estos otros objetos proporcionan métodos de devolución de llamada desde el entorno del host que proporcionan * onCreated y onDestroy, en los que solo podemos enlazar a este objeto desde OnCreated y * out bind onDestory. * Este tipo de métodos de devolución de llamada, tiempo de ejecución temporal es controlado por nuestro entorno de host * y no garantizan que el comportamiento/orden de ejecución del Ciclo de vida de la actividad y estos métodos de devolución de llamada * permanezcan uniformes. * Con fines de desarrollo, las interacciones y el orden de ejecución se pueden llamar técnicamente indefinidos *, ya que depende del implementador de la implementación del host, samsung, sony, htc. * * Consulte el siguiente documento del desarrollador: https://developer.android.com/reference/android/app/Activity.html * Cita: * Si una actividad está completamente oscurecida por otra actividad, se detiene. Aún conserva todos los estados * y la información de los miembros, sin embargo, ya no es visible para el usuario, por lo que su ventana está * oculta y, a menudo, el sistema la eliminará cuando se necesite memoria en otro lugar. * EndQuato: * * Si la actividad no está oculta, no se habrán llamado a las devoluciones de llamada que se esperaba del sistema host *, como los métodos OnCreate y OnDestory interfaz de devolución de llamada de SurfaceView. * Esto significa que tendrá que detener el objeto que se ha vinculado a SurfaceView, como una cámara * en pausa, y nunca volverá a vincular el objeto, ya que nunca se llamará a la devolución de llamada OnCreate. * */
public abstract class WaitAllActiveExecuter<Size>
{
private SparseArray<Boolean> mReferancesState = null;
// Use a dictionary and not just a counter, as hosted code
// environment implementer may make a mistake and then may double executes things.
private int mAllActiveCount = 0;
private String mContextStr;
public WaitAllActiveExecuter(String contextStr, int... identifiers)
{
mReferancesState = new SparseArray<Boolean>(identifiers.length);
mContextStr = contextStr;
for (int i = 0; i < identifiers.length; i++)
mReferancesState.put(identifiers[i], false);
}
public void ActiveState(int identifier)
{
Boolean state = mReferancesState.get(identifier);
if (state == null)
{
// Typically panic here referance was not registered here.
throw new IllegalStateException(mContextStr + "ActiveState: Identifier not found '" + identifier + "'");
}
else if(state == false){
mReferancesState.put(identifier, true);
mAllActiveCount++;
if (mAllActiveCount == mReferancesState.size())
RunActive();
}
else
{
Log.e(mContextStr, "ActivateState: called to many times for identifier '" + identifier + "'");
// Typically panic here and output a log message.
}
}
public void DeactiveState(int identifier)
{
Boolean state = mReferancesState.get(identifier);
if (state == null)
{
// Typically panic here referance was not registered here.
throw new IllegalStateException(mContextStr + "DeActiveState: Identifier not found '" + identifier + "'");
}
else if(state == true){
if (mAllActiveCount == mReferancesState.size())
RunDeActive();
mReferancesState.put(identifier, false);
mAllActiveCount--;
}
else
{
Log.e(mContextStr,"DeActiveState: State called to many times for identifier'" + identifier + "'");
// Typically panic here and output a log message.
}
}
private void RunActive()
{
Log.v(mContextStr, "Executing Activate");
ExecuterActive();
}
private void RunDeActive()
{
Log.v(mContextStr, "Executing DeActivate");
ExecuterDeActive();
}
abstract public void ExecuterActive();
abstract public void ExecuterDeActive();
}
Ejemplo de Aplicación y uso de la clase, que se ocupa o el comportamiento indefinido de ambiente anfitrión androide implementadores.
private final int mBCTSV_SurfaceViewIdentifier = 1;
private final int mBCTSV_CameraIdentifier = 2;
private WaitAllActiveExecuter mBindCameraToSurfaceView =
new WaitAllActiveExecuter("BindCameraToSurfaceViewe", new int[]{mBCTSV_SurfaceViewIdentifier, mBCTSV_CameraIdentifier})
{
@Override
public void ExecuterActive() {
// Open a handle to the camera, if not open yet and the SurfaceView is already intialized.
if (mCamera == null)
{
mCamera = Camera.open(mCameraIDUsed);
if (mCamera == null)
throw new RuntimeException("Camera could not open");
// Look at reducing the calls in the following two methods, some this is unessary.
setDefaultCameraParameters(mCamera);
setPreviewSizesForCameraFromSurfaceHolder(getSurfaceHolderForCameraPreview());
}
// Bind the Camera to the SurfaceView.
try {
mCamera.startPreview();
mCamera.setPreviewDisplay(getSurfaceHolderForCameraPreview());
} catch (IOException e) {
e.printStackTrace();
ExecuterDeActive();
throw new RuntimeException("Camera preview could not be set");
}
}
@Override
public void ExecuterDeActive() {
if (mCamera != null)
{
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
};
@Override
protected void onPause() {
mBindCameraToSurfaceView.DeactiveState(mBCTSV_CameraIdentifier);
Log.v(LOG_TAG, "Activity Paused - After Super");
}
@Override
public void onResume() {
mBindCameraToSurfaceView.ActiveState(mBCTSV_CameraIdentifier);
}
private class SurfaceHolderCallback implements SurfaceHolder.Callback
{
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.v(LOG_TAG, "Surface Changed");
}
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.v(LOG_TAG, "Surface Created");
mBindCameraToSurfaceView.ActiveState(mBCTSV_SurfaceViewIdentifier);
}
public void surfaceDestroyed(SurfaceHolder arg0) {
Log.v(LOG_TAG, "Surface Destoryed");
mBindCameraToSurfaceView.DeactiveState(mBCTSV_SurfaceViewIdentifier);
}
}
¿En qué nivel Plaform/API de Android está desarrollando? – FerranB