2010-12-14 39 views
18

Cách tốt nhất để kiểm tra xem Dịch vụ Android có đang chạy không? Tôi biết về API ActivityManager, nhưng có vẻ như việc sử dụng API không được thông báo cho các kịch bản tương tự như của tôi (source). Tôi cũng biết khả năng sử dụng các biến toàn cầu/liên tục để duy trì trạng thái của một dịch vụ.Android: Kiểm tra xem dịch vụ có đang chạy hay không. bindService

Tôi đã cố gắng sử dụng bindService với cờ thiết lập để 0, nhưng tôi có những vấn đề tương tự như người trên nguồn liên kết (ngoại lệ duy nhất là, tôi đã cố gắng các bindService với một dịch vụ địa phương).

Cuộc gọi sau

getApplicationContext().bindService(new Intent(getApplicationContext(), 
     MyService.class), mServiceConnection, 0); 

luôn trả về true, nhưng không được kết nối. Đây có phải là hành vi mong đợi không? Dường như với tôi bindService sẽ trả về false nếu dịch vụ chưa chạy (nó không phải là, tôi đã kiểm tra) hoặc nếu cờ BIND_AUTO_CREATE không được đặt (một lần nữa, nó không phải là).

Trả lời

10

Tôi có cùng một vấn đề; dường như giải pháp nổi tiếng nhất là tạo ra một boolean tĩnh công khai trong WhateverService, được đặt thành true trong khi onCreate (hoặc onStartCommand, sự lựa chọn của bạn) và false trong onDestroy. Sau đó bạn có thể truy cập nó từ bất kỳ lớp nào khác trong cùng một gói ứng dụng. Điều này có thể là chủng tộc mặc dù. Không có API trong Android để kiểm tra xem một dịch vụ có đang chạy hay không (không có tác dụng phụ): Xem http://groups.google.com/group/android-developers/browse_thread/thread/8c4bd731681b8331/bf3ae8ef79cad75d

Tôi cho rằng điều kiện cuộc gọi xuất phát từ việc hệ điều hành có thể giết dịch vụ từ xa (trong một quy trình khác) bất cứ lúc nào . Kiểm tra một dịch vụ địa phương (cùng một quá trình), như đã đề xuất ở trên, dường như không có cuộc đua với tôi - nếu hệ điều hành giết dịch vụ, nó sẽ giết bất cứ điều gì đã kiểm tra trạng thái của nó.

0

Bạn định làm gì nếu dịch vụ đang chạy/không chạy? Tại sao không chỉ gọi startService(). Điều đó sẽ tạo ra nó nếu nó không chạy, và nếu nó là nó sẽ gọi phương thức onStart() của nó.

+1

Hãy nói rằng tôi sẽ muốn in một thông báo "Dịch vụ đang chạy" hoặc "Dịch vụ không chạy". Đó là lý do tại sao tôi phải nhận được thông tin nếu dịch vụ đang chạy hay không. Tôi không thể làm điều đó bằng cách gọi startService. – Igor

+0

Nhưng tại sao bạn phải in thông điệp này? Chỉ có 2 thứ bạn có thể làm nếu dịch vụ không chạy. Hoặc là bắt đầu hay không. – Falmarri

+1

Vì tôi muốn thông báo cho người dùng nếu dịch vụ đang chạy hay không. Người dùng nên bắt đầu và dừng dịch vụ theo cách thủ công (thông qua một nút bấm).Khi người dùng đóng hoạt động (nút BACK), dịch vụ sẽ vẫn chạy. Và hoạt động sẽ biết, khi người dùng bắt đầu nó vào lần sau, dịch vụ đã chạy. – Igor

1

Tôi có cùng nhu cầu và thấy rằng đang chạy .bindService với một thứ khác đã bị ràng buộc, rằng nó sẽ gây ra lỗi. Tôi đã làm điều này ngay trước khi chạy .bindService

try{ 
    context.unbindService(fetch_connection); 
} catch (IllegalArgumentException e){ 
    System.out.println("Unbinding didn't work. little surprise"); 
} 
+0

Điều này chỉ kiểm tra xem bạn có bị ràng buộc với dịch vụ không. Không, nếu nó bắt đầu hay không. – Falmarri

11

Sử dụng một sở thích chia sẻ để tiết kiệm dịch vụ chạy cờ.

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    int res = super.onStartCommand(intent, flags, startId); 
    setRunning(true); 
    return res; 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    setRunning(false); 
} 

private void setRunning(boolean running) { 
    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); 
    SharedPreferences.Editor editor = pref.edit(); 

    editor.putBoolean(PREF_IS_RUNNING, running); 
    editor.apply(); 
} 

public static boolean isRunning(Context ctx) { 
    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(ctx.getApplicationContext()); 
    return pref.getBoolean(PREF_IS_RUNNING, false); 
} 
+4

Đây không phải là một ý tưởng hay, SharedPreferences được lưu giữ trong kho lưu trữ không dễ bay hơi vì vậy nếu vì lý do nào đó thiết bị bị lỗi hoặc mất điện thì 'onDestroy' của bạn sẽ không được gọi và lần sau khi bạn khởi động ứng dụng của bạn sẽ nghĩ rằng dịch vụ đang chạy mặc dù nó không phải là. – satur9nine

+0

Vâng, tôi đồng ý. SharedPreferences không dành cho nó. Tuy nhiên, dịch vụ chạy pref có thể được gỡ bỏ khi khởi động ứng dụng. Một cách khác: dịch vụ lưu trữ chạy bool var trong đối tượng Application. –

+0

onDestroy không phải lúc nào cũng gọi – Nepster

2

Phương pháp khác:

public static boolean isServiceRunning(Context ctx, String serviceClassName) { 
    ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE); 
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 
     if (TrackingService.class.getName().equals(serviceClassName)) { 
      return true; 
     } 
    } 
    return false; 
} 
+0

Khi tôi sử dụng mã trên, nó chỉ cho tôi thông tin về các dịch vụ đang chạy của hệ thống. Tôi đang tìm tất cả các dịch vụ bao gồm cả dịch vụ mà tôi đã tạo – user1810931

0

trong hoạt động của bạn u chỉ có thể kiểm tra xem nó bằng cách sử dụng thể hiện của dịch vụ của bạn trong trường hợp của tôi, tôi thực hiện nó bằng cách sử

button.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 

      Intent intent=new Intent(MainActivity.this, MyService.class); 
      //startService(intent); 
      bindService(intent,serviceConnection,BIND_AUTO_CREATE); 
      if (myService!=null) 
      { 
       myService.RecData(editText.getText().toString()); 
      } 
     } 
    }); 
} 

ServiceConnection serviceConnection=new ServiceConnection() { 
    @Override 
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) { 
     Toast.makeText(MainActivity.this,"onServiceConnected called",Toast.LENGTH_SHORT).show(); 
     MyService.MyBinder myBinder= (MyService.MyBinder) iBinder; 
     myService= myBinder.getServiceInstant(); 
     myService.SetActivity(MainActivity.this); 
     myService.RecData(editText.getText().toString()); 
    } 
Các vấn đề liên quan