Ecco una soluzione alternativa per tutti i metodi di callback, che possono essere tutti soggetti allo stesso comportamento di ordine evento non definito con ciclo di attività. A meno che non si proceda a ispezionare tutto il codice di Android per ogni richiamo che si utilizza per determinare il trigger di origine e chi controlla le implementazioni e sperare che la base di codice non venga modificata in futuro, si può davvero affermare che l'ordine di eventi tra le richiamate e gli eventi del ciclo di vita delle attività potrebbero essere garantiti.
In questo momento queste interazioni di ordine possono essere generalmente definite comportamento non definito, a fini di sviluppo.
Quindi sarebbe meglio gestire sempre questo comportamento indefinito, in modo tale che non sarà mai un problema in primo luogo, assicurarsi che gli ordini siano comportamenti definiti.
Il mio Sony Xperia, ad esempio, in modalità sleep, esegue il ciclo della mia app corrente, distruggendo l'app, quindi riavviandola e inserendola nello stato di pausa, che ci crediate o meno.
evento quanto ordinato test comportamento di Google offre in prova il loro SDK come speciali costruire per ambiente host implementa Non lo so, ma sicuramente bisogno di fare uno sforzo per garantire, comportamenti di ordini di eventi sono tutti bloccati per essere piuttosto severo in materia.
https://code.google.com/p/android/issues/detail?id=214171&sort=-opened&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened
import android.util.Log; import android.util.SparseArray;
/** * Creato da woliver il 24/06/2016. * * Ambiente host Android, determina un ciclo di vita attività per OnCreate, onStart, onResume, onPause, onStop, onDestory, * dove da parte nostra è necessario rilasciare memoria e handle per altre applicazioni da utilizzare. * Quando si riprende, a volte è necessario riavvolgere e attivare questi elementi con altri oggetti. * In genere questi altri oggetti forniscono metodi di callback dall'ambiente host che forniscono * un onCreated e onDestroy, in cui possiamo solo associare a questo oggetto da OnCreated e perdere * bind onDestory. * Questi tipi di metodi di richiamata, il tempo necessario per l'esecuzione è il controller dal nostro ambiente host * e non garantiscono che il comportamento/l'ordine di esecuzione del ciclo di vita dell'attività e questi metodi di richiamata * rimangano coerenti. * Ai fini dello sviluppo, le interazioni e l'ordine di esecuzione possono tecnicamente essere definiti non definiti * in quanto dipende dall'implementatore dell'implementazione host, samsung, sony, htc. * * Vedere il documento di sviluppo seguente: https://developer.android.com/reference/android/app/Activity.html * Citazione: * Se un'attività è completamente nascosta da un'altra attività, viene interrotta. Conserva ancora tutto lo stato * e le informazioni sui membri, tuttavia, non è più visibile all'utente, quindi la sua finestra è * nascosta e verrà spesso uccisa dal sistema quando la memoria è necessaria altrove. * EndQuato: * * Se l'attività non è nascosta, eventuali callback che ci si sarebbe aspettati di chiamare dal sistema host *, non sono stati chiamati, come i metodi OnCreate e OnDestory interfacciano il callback di SurfaceView. * Ciò significa che è necessario interrompere l'oggetto che è stato associato a SurfaceView come una fotocamera * in pausa e non potrà mai riassociare l'oggetto in quanto il callback OnCreate non verrà mai chiamato. * */
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();
}
esempio di implementazione e l'uso di classe, che si occupa o il comportamento indefinito di Android ambiente ospite esecutori.
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);
}
}
In quale livello di Plaform/API Android si sta sviluppando? – FerranB