Đây là giải pháp thay thế cho tất cả các phương thức gọi lại, tất cả có thể phải tuân theo cùng hành vi đơn hàng sự kiện chưa xác định với chu kỳ hoạt động. Trừ khi bạn sẽ kiểm tra tất cả mã android cho mỗi cuộc gọi trở lại bạn sử dụng để xác định trình kích hoạt gốc và ai kiểm soát việc triển khai và hy vọng rằng cơ sở mã không thay đổi trong tương lai, có thể thực sự tuyên bố rằng thứ tự sự kiện giữa các cuộc gọi lại và các sự kiện vòng đời hoạt động có thể được đảm bảo.
Hiện tại, các tương tác này của đơn đặt hàng thường có thể được gọi là hành vi không xác định, cho mục đích phát triển.Vì vậy, tốt nhất là luôn luôn xử lý chính xác hành vi không xác định này, như vậy nó sẽ không bao giờ là một vấn đề ở nơi đầu tiên, bằng cách đảm bảo các đơn đặt hàng được xác định hành vi.
Ví dụ Sony Xperia của tôi về chế độ ngủ, xoay vòng ứng dụng hiện tại của tôi bằng cách hủy ứng dụng và sau đó khởi động lại và đặt nó vào trạng thái tạm dừng, tin hay không.
Bao nhiêu sự kiện sắp xếp hành vi thử nghiệm google cung cấp trong SDK của họ như là xây dựng thử nghiệm đặc biệt cho môi trường máy chủ thực hiện tôi không biết, nhưng họ chắc chắn cần phải nỗ lực để đảm bảo, hành vi của các đơn đặt hàng sự kiện đều bị khóa khá nghiêm khắc về vấn đề này.
https://code.google.com/p/android/issues/detail?id=214171&sort=-opened&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened
nhập android.util.Log; nhập android.util.SparseArray;
/** * Được tạo bởi woliver vào ngày 2016/06/24. * * Môi trường máy chủ Android, quy định Chu kỳ hoạt động cho OnCreate, onStart, onResume, onPause, onStop, onDestory, * nơi chúng tôi yêu cầu phát hành bộ nhớ và xử lý cho các ứng dụng khác để sử dụng. * Khi tiếp tục, chúng tôi được yêu cầu vào các thời điểm để rebind và kích hoạt các mục này với các đối tượng khác. * Thông thường các đối tượng khác cung cấp các phương thức gọi lại từ môi trường máy chủ cung cấp * một onCreated và onDestroy, trong đó chúng ta chỉ có thể liên kết với đối tượng này từ OnCreated và loose * out bind onDestory. * Các loại phương thức gọi lại này, thời gian chạy ngẫu nhiên là điều khiển bởi môi trường máy chủ * và không đảm bảo rằng hành vi/thứ tự thực hiện Vòng đời hoạt động và các phương thức gọi lại * vẫn nhất quán. * Với mục đích phát triển, các tương tác và thứ tự thực thi có thể được gọi là undefined * vì nó phụ thuộc vào trình triển khai thực hiện máy chủ, samsung, sony, htc. * * Xem tài liệu nhà phát triển sau: https://developer.android.com/reference/android/app/Activity.html * Trích: * Nếu hoạt động bị che khuất hoàn toàn bởi một hoạt động khác, nó sẽ bị dừng lại. Tuy nhiên, nó vẫn giữ lại tất cả trạng thái * và thông tin thành viên, nó không còn hiển thị với người dùng nữa nên cửa sổ của nó là * bị ẩn và thường sẽ bị hệ thống giết khi cần bộ nhớ ở nơi khác. * EndQuato: * * Nếu hoạt động không bị ẩn, thì bất kỳ cuộc gọi lại nào được mong đợi sẽ được gọi bởi máy chủ * hệ thống, sẽ không được gọi, chẳng hạn như giao diện OnCreate và OnDestory gọi lại SurfaceView. * Điều này có nghĩa là bạn sẽ phải dừng đối tượng đã được liên kết với SurfaceView chẳng hạn như máy ảnh * tạm dừng và sẽ không bao giờ rebind đối tượng khi cuộc gọi lại OnCreate sẽ không bao giờ được gọi. * */
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();
}
Ví dụ về thực hiện và sử dụng các lớp, trong đó đề với hoặc hành vi không xác định của android chủ môi trường người thực hiện.
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);
}
}
Bạn đang phát triển cấp Plaform/API ở đâu? – FerranB