2012-01-31 27 views
8

Tôi gặp vấn đề lớn khi dừng dịch vụ, phát tệp âm thanh. Tôi muốn dừng dịch vụ hiện tại trước khi tôi phát một tệp khác.Android: stopService() không gọi onDestroy()!

Hoạt động:

public void playTrack(View view){  
    Intent i=new Intent(this,playService.class); 
    i.setAction("com.c0dehunterstudios.relaxer.PLAY"); 

    if(isPlaying){ 
      stopService(i); 
      isPlaying=false; 
      Log.v("ACTIVITY", "Stopping.."); 
    } 

    startService(i); 
    isPlaying=true; 
} 

dịch vụ:

public void OnDestroy(){ 
    Log.v("SERVICE","Service killed"); 
    player.stop(); 
    super.onDestroy(); 
} 

Nhưng buồn thay nó không hoạt động - thực sự nó không thậm chí đi xuống "Dịch vụ giết" bên OnDestroy().

Tôi đang làm gì sai?

Trả lời

15

Đầu tiên, đó là onDestroy, không phải OnDestroy. Thứ hai, bạn phải sử dụng các chú thích @Override cho thời gian biên dịch kiểm tra, do đó, mã dịch vụ của bạn nên nhìn hơi như thế này:

@Override 
public void onDestroy(){ 
    Log.v("SERVICE","Service killed"); 
    player.stop(); 
    super.onDestroy(); 
} 
+0

Cảm ơn bạn, bạn giải quyết "vấn đề" của tôi. –

+4

Ngoài ra, nếu bạn đang sử dụng Eclipse (như hầu hết mọi người đang sử dụng Android, tôi nghĩ), hãy thử sử dụng lệnh menu "Source-> Override/Implement Methods" - điều này sẽ tạo ra một hàm cho hàm sẵn sàng để bạn điền vào và bạn sẽ không thể phạm sai lầm với tên. –

+0

Xin cảm ơn, lời khuyên tốt! –

5

Tôi đã có một vấn đề tương tự ngay cả với onDestroy thiết lập đúng - câu trả lời cho điều này có thể được hữu ích cho những người đến trang này. Đối với tôi, onDestroy không được gọi ngay lập tức trong stopService, đôi khi trong một thời gian rất dài - để lại dịch vụ làm việc khi nó phải dừng lại.

Câu trả lời là hành vi này được mong đợi - tôi có thể đoán nhưng không biết chính xác lý do. Vì vậy, giải pháp của tôi trong trường hợp này là để tạo ra một phương pháp tĩnh công cộng để ngăn chặn các hành động của dịch vụ bằng tay, mà xảy ra tại thời điểm nó được gọi, sau đó stopService() sẽ gọi onDestroy trong thời gian tốt ...

In trường hợp cho ví dụ này (có lẽ đã qua lâu rồi, tôi có thể quyết định giữ cho dịch vụ chạy cho đến khi ứng dụng được mong đợi là hoàn toàn ứng dụng, nhưng cung cấp các cách để thay đổi tệp âm thanh, trong khi dịch vụ vẫn hoạt động.

2

Đầu tiên, bạn cần phải làm rõ có bao nhiêu loại dịch vụ trong Android. AFAIK, có:

  • Dịch vụ trước mặt
  • Dịch vụ nền.
  • Dịch vụ ràng buộc.
  • Dịch vụ ý định.

Các dịch vụ này dừng theo những cách khác nhau.

  • Foreground: chỉ dừng lại khi bạn cố tình ngăn chặn nó bằng cách gọi stopService() trong hoạt động hoặc mảnh nơi bạn bắt đầu dịch vụ, hoặc gọi stopItself() phục vụ riêng của mình. Và Xin lưu ý chỉ những dịch vụ kích hoạt phương pháp này là onDestroy().
  • Nền: stopService()stopItself() hoạt động theo cách tương tự như tiền cảnh. Hơn nữa, bạn nên biết dịch vụ này nằm trong cùng một luồng với hoạt động hoặc đoạn gọi nó, vì vậy nếu bạn phá hủy hoạt động hoặc đoạn, dịch vụ này cũng sẽ dừng lại, nhưng không gọi onDestroy(). Nó cơ bản phá hủy dưới lòng đất.Vì vậy, nếu bạn muốn bắt khi dịch vụ này dừng lại bạn cần phải thêm android:stopWithTask="false" khi tuyên bố dịch vụ trong tập tin Manifest như thế này:

    <application> 
        //.... 
        <service android:name=".services.catchingStopService" 
         android:stopWithTask="false" /> 
        //.... 
    </application> 
    

    Và bây giờ trong lớp dịch vụ của bạn, bạn có thể ghi đè phương pháp này mà gây nên khi từng này phục vụ điểm dừng :

    @Override 
    public void onTaskRemoved(Intent rootIntent) { 
        super.onTaskRemoved(rootIntent); 
        // Your job when the service stops. 
    } 
    
  • ràng buộc: bạn cần phải xử lý bằng cách tự của bạn bằng cách bindService()unbindService(), bạn sẽ tìm ra nó hoàn toàn giống như starService()stopService()

  • Mục đích: loại dịch vụ này tự dừng lại khi nó kết thúc công việc của mình. Và bạn có thể sử dụng ResultReceiver để giao tiếp giữa dịch vụ và hoạt động hoặc đoạn. Nó tương tự như BroadcastReceiver. Bạn có thể tìm kiếm ví dụ trên Google một cách dễ dàng.

Tóm tắt: căn cứ vào mục đích của bạn, chọn loại dịch vụ thỏa mãn bạn. Và tất cả họ đều đồng ý với:

  • Không được tính onDestroy() để biết khi nào dịch vụ dừng lại, bởi vì nó đôi khi được gọi là ngầm; chính xác hơn, onDestroy gọi khi các cuộc gọi stopService() hoặc stopItSelf() (BoundService hoạt động theo cách tương tự, nhưng theo phương pháp tương tự, có thể unBind(), tôi chưa thử nghiệm ).
  • Sử dụng thuộc tính android: stopWithTask = "false", thay vào đó để biết thời điểm dịch vụ thực sự dừng.
  • Tất cả các loại dịch vụ dừng lại khi tắt thiết bị hoặc hệ điều hành sẽ tự động xóa nếu rò rỉ bộ nhớ thiết bị.
  • Bạn cũng nên xem xét trả lại cờ bằng cách onStartCommand() đến có thể xử lý khi dịch vụ ngừng hoạt động lại như dịch vụ khởi động lại hoặc điều gì đó. Dưới đây là một số từ khóa mà bạn có thể tìm kiếm:
    • START_STICKY
    • <action android:name="android.intent.action.BOOT_COMPLETED" />
    • <action android:name="android.intent.action.ACTION_SHUTDOWN" />
    • <actionandroid:name="android.intent.action.QUICKBOOT_POWEROFF" />
Các vấn đề liên quan