これは、すべてのコールバックメソッドの代替ソリューションです。これらはすべて、アクティビティサイクルで同じ未定義のイベント順序の動作の対象となる可能性があります。オリジントリガーを決定するために使用する各コールバックのすべてのAndroidコードを検査し、実装を制御し、コードベースが将来変更されないことを期待しない限り、コールバック間のイベントの順序を実際に述べることができますアクティビティのライフサイクルイベントが保証される可能性があります。
現在、これらの順序の相互作用は、通常、開発目的では未定義動作と呼ばれます。
したがって、順序が定義された動作であることを確認することにより、最初から問題にならないように、この未定義の動作を常に正しく処理することが最善です。
たとえば、私のSony Xperiaは、スリープ時に、アプリを破棄してから再起動し、信じられないかもしれませんが一時停止状態にすることで、現在のアプリを循環させます。
ホスト環境の特別なテストビルドとしてGoogleがSDKで提供するイベント順序の動作テストの量はわかりませんが、イベントの順序の動作はすべて、かなり厳密にすることでロックダウンされるように努力する必要があります。案件。
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;
/ ***2016/06/24にwoliverによって作成されました。* * Androidホスト環境は、OnCreate、onStart、onResume、onPause、onStop、onDestoryのアクティビティライフサイクルを指示します。*他のアプリケーションが使用するためにメモリとハンドルを解放する必要があります。*再開時に、これらのアイテムを他のオブジェクトと再バインドしてアクティブ化する必要がある場合があります。*通常、これらの他のオブジェクトは、onCreatedおよびonDestroyを提供するホスト環境からのコールバックメソッドを提供します。このメソッドでは、OnCreatedからのみこのオブジェクトにバインドでき、*onDestoryのバインドを解除します。*これらのタイプのコールバックメソッド、実行時間はホスト環境によって制御されます*。これらは、アクティビティライフサイクルとこれらのコールバックメソッドの動作/実行順序が一貫していることを保証するものではありません。*開発の目的で、相互作用と実行の順序は、ホスト実装の実装者であるsamsung、sony、htc次第であるため、技術的には未定義と呼ぶことができます。**次の開発者向けドキュメントを参照してください。https://developer.android.com/reference/android/app/Activity.html
*見積もり:*アクティビティが別のアクティビティによって完全に隠されている場合、そのアクティビティは停止されます。それでもすべての状態とメンバー情報が保持されますが、ユーザーには表示されなくなるため、ウィンドウは非表示になり、他の場所でメモリが必要になるとシステムによって強制終了されることがよくあります。* EndQuato:* *アクティビティが非表示になっていない場合、OnCreateメソッドやOnDestoryメソッドインターフェイスのSurfaceViewコールバックなど、ホストシステムによって呼び出されると予想されるコールバックは呼び出されません。*これは、カメラなどのSurfaceViewにバインドされたオブジェクトを一時停止する必要があり、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();
}
実装とクラスの使用の例。これは、Androidホスト環境の実装者の未定義の動作を処理します。
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);
}
}