2011-11-29 31 views
10

Trong ứng dụng của tôi, tôi muốn tệp phương tiện phát và tiếp tục phát nếu người dùng xoay màn hình (hủy Hoạt động), nhưng tôi muốn nó ngừng phát nếu người dùng chuyển sang Hoạt động khác hoặc Hoạt động khác xuất hiện điều này, họ nhấn nút quay lại, bất cứ điều gì.Làm cách nào để biết khi nào có thay đổi cấu hình xảy ra trong Froyo?

Tôi tin rằng có một API cho điều này trong Honeycomb, nhưng tôi cần một cái gì đó sẽ làm việc trong Android 2.2.

Tôi không muốn sử dụng onConfigurationChanged để xử lý tất cả các thay đổi cấu hình - âm thanh như rất nhiều công việc và các lỗi tiềm ẩn - và vấn đề với onRetainNonConfigurationInstance() là nó không chạy cho đến sau khi onStop cháy - nhưng onPause sẽ là nơi hợp lý để tạm dừng phương tiện, nếu thích hợp.

Có cách nào, trong onPause, để biết liệu Hoạt động có bị tạm dừng cho thay đổi cấu hình so với một lý do khác không?

Trả lời

9

Giải pháp của bạn có ít nhất một vấn đề tiềm ẩn.

Theo tài liệu Android:

Một số cấu hình thiết bị có thể thay đổi trong thời gian chạy (chẳng hạn như hướng màn hình, tính khả dụng bàn phím, và ngôn ngữ). Khi một thay đổi như vậy xảy ra, Android khởi động lại Activity đang hoạt động (onDestroy() được gọi, tiếp theo là onCreate()).

Kiểm tra thay đổi trong vòng quay chỉ xử lý một trường hợp. Vì đây có thể là nguyên nhân phổ biến nhất của thay đổi cấu hình, đây là giải pháp OK. Nhưng điều gì sẽ xảy ra nếu bạn có thể xử lý tất cả các trường hợp, hiện có hoặc được thêm vào trong một số phiên bản tương lai của Android, mà không phải tự mình xử lý cấu hình?

Đã cập nhật để sử dụng onRetainNonConfigurationInstance. Tài liệu Android có điều này để nói về điều này:

Được gọi bởi hệ thống, như là một phần phá hủy hoạt động do thay đổi cấu hình, khi biết rằng một cá thể mới sẽ ngay lập tức được tạo cho cấu hình mới.

Cũng thay đổi chuỗi thành super.onDestroy() xảy ra sau khi dừng phương tiện nhưng không hoàn toàn chắc chắn về điều đó. Đoán nó phụ thuộc vào những gì phương tiện dừng phương tiện, và những gì có hiệu lực phá hủy có thể có trên dừng phương tiện truyền thông.

private Boolean mConfigurationChange = false; 

public Object onRetainNonConfigurationInstance() { 
    mConfigurationChange = true; 
    return null; 
} 

public void onDestroy() { 
    if (!mConfigurationChange) { 
     // Code to stop media file goes here. 
    } 
    super.onDestroy(); 
}  
+1

Một ý tưởng thú vị, Julian, cảm ơn bạn vì ví dụ chi tiết. Khi tôi thêm android: configChanges = "orientation" vào Hoạt động có liên quan trong tệp kê khai, nó sẽ có hiệu lực, nhưng không như tôi mong đợi. onConfigurationChanged KHÔNG kích hoạt ... nhưng onPause/onStop/onDestroy không bao giờ được gọi. Vì vậy, đó là một cách để giải quyết vấn đề "xoay màn hình phá hủy Hoạt động" nhưng không theo cách được Google đề xuất. Cảm ơn mặc dù! –

+0

Xem câu trả lời cập nhật. Không liên quan đến thay đổi đối với tệp kê khai và onDestroy() vẫn được gọi. –

+1

Câu trả lời mới dường như hoạt động! OnRetainNonConfigurationInstance kích hoạt sau onStop và trước onDestroy, và với mã onDestroy chính xác này có thể cho biết liệu nó có tắt hay không để thay đổi cấu hình hay không. Cảm ơn! –

0

Bạn có thể thử nghe ý định ACTION_CONFIGURATION_CHANGED và đặt cờ nội bộ cho biết tạm dừng là từ thay đổi cấu hình.

Tôi không chắc chắn liệu bạn có nhận được ý định kịp thời hay không và bạn sẽ được đảm bảo rằng nó sẽ đến đúng lúc vì nó có thể không đồng bộ. Có thể có giá trị một thử mặc dù.

2

Cuối cùng tôi đã tìm ra câu trả lời cho câu hỏi của riêng mình!

public class MyActivity extends Activity { 

    Display display; 
    int originalRotation; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
     originalRotation = display.getRotation(); 
    } 

    public boolean endingDueToConfigurationChanging() { 
    int newRotation = display.getRotation(); 
    return (newRotation != originalRotation); 
    } 
} 

Display.getRotation() được thiết kế để trả về hằng số cho biết thiết bị có xoay 0, 90, 180 hoặc 270 độ không. Tuy nhiên, khi thiết bị được xoay, giá trị này được cập nhật trước khi hoạt động kết thúc - nó thực sự được cập nhật sớm nhất trong onPause()! Vì vậy, nếu bạn so sánh giá trị trong onPause() (giá trị mới) với giá trị onCreate() (giá trị ban đầu) thì bạn biết Activity sẽ tắt do xoay màn hình hay không.

+0

Điều gì sử dụng "endingDueToConfigurationChanging"? Tôi nghĩ có lẽ đây là một số cuộc gọi API Android và nếu bạn trả về false, nó sẽ không kết thúc sau khi tất cả, nhưng dường như nó không phải, và tôi không thể nói làm thế nào bạn đang sử dụng nó. – Michael

+0

Đó là năm năm và một số công ty trước đây ... Tôi sợ tôi không có ý tưởng. Tôi đoán tôi vô tình bỏ qua một số mã gọi endDueToConfigurationChanging. Oh well. Hiện có câu trả lời tốt hơn. –

0

Bạn cũng có thể thử sử dụng View#onConfigurationChanged trong trường hợp có thể áp dụng trong trường hợp của bạn (nghĩa là - bạn có chế độ xem cho trình phát đa phương tiện và có tham chiếu đến nó trong chế độ xem).

+0

Cảm ơn câu trả lời, iLate, nhưng như tôi đã nói trong câu hỏi ban đầu, nếu tôi sử dụng onConfigurationChanged thì tôi sẽ thay thế xử lý xoay vòng của Android bằng mã của riêng tôi - nghĩa là tôi sẽ phải thay đổi bố cục theo cách thủ công, v.v. nhiều việc phải làm cho mục tiêu đơn giản của tôi là biết cấu hình có thay đổi hay không. –

+0

Tôi đang yêu cầu bạn ghi đè View # onConfigurationChanged, nhưng không phải là Hoạt động # onConfigurationChanged. Phương pháp này được gọi là mọi lúc trước hoạt động của bạn đã được tạo lại sau khi thay đổi cấu hình, bất kể bạn đã chỉ định gì trong tệp kê khai của mình. – asenovm

+0

Một ví dụ hoàn chỉnh có thể giúp tôi hiểu rõ hơn. Tôi nghĩ bạn đang đề xuất tạo lớp View tùy chỉnh và ghi đè lênConfigurationChanged ở đó? Nó không hoạt động trừ khi tôi thêm android: configChanges = "orientation" vào Activity có liên quan trong manifest, và sau đó onPause/onStop/onDestroy chưa bao giờ được gọi. Cảm ơn mặc dù. –

6

Trước khi tổ ong, onRetainNonConfigurationInstance() như được đề cập trong câu trả lời được chấp nhận là cách tốt nhất để thực hiện việc này.

Bắt đầu với Honeycomb, đó là phản đối, nhưng có một cách đơn giản hơn nhiều: gọi isChangingConfigurations() thay vào đó, trong bất kỳ của bạn onPause()/onStop()/onDestroy().

Cuối cùng, nếu sử dụng các thư viện hỗ trợ FragmentActivity ( android.support.v4.app.FragmentActivity) trên trước Honeycomb, onRetainNonConfigurationInstance() được tuyên bố chính thức, nhưng bạn có thể ghi đè lên onRetainCustomNonConfigurationInstance() thay cho tác dụng tương tự.

Các vấn đề liên quan