2012-03-31 22 views
17

Tôi đang liên kết với dịch vụ bằng cách này:Android: tham số đường chuyền qua dịch vụ từ Hoạt động

Hoạt động lớp:

ListenLocationService mService; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
     ... 
     Intent intent = new Intent(this, ListenLocationService.class); 
     intent.putExtra("From", "Main"); 
     bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 
     ... 
} 

private ServiceConnection mConnection = new ServiceConnection() { 

     public void onServiceConnected(ComponentName className, 
       IBinder service) { 
      LocalBinder binder = (LocalBinder) service; 
      mService = binder.getService();   
     } 

     public void onServiceDisconnected(ComponentName arg0) { 
     } 
    }; 

Đây là onBind phương pháp Dịch vụ tôi:

@Override 
public IBinder onBind(Intent intent) { 
    Bundle extras = intent.getExtras(); 
    if(extras == null) 
     Log.d("Service","null"); 
    else 
    { 
     Log.d("Service","not null"); 
     String from = (String) extras.get("From"); 
     if(from.equalsIgnoreCase("Main")) 
      StartListenLocation(); 
    } 
    return mBinder; 
} 

Vì vậy, tôi có "null" trong LogCat - gói là null trong s mặc dù tôi đã thực hiện intent.putExtra trước bindService

Nói chung, Dịch vụ hoạt động tốt. Tuy nhiên tôi chỉ cần gọi StartListenLocation(); chỉ từ hoạt động chính của ứng dụng (tôi quyết định thực hiện việc này bằng cách gửi cờ).

Làm cách nào để gửi dữ liệu đến dịch vụ? Hoặc có thể có một cách khác để kiểm tra xem hoạt động nào đã được đưa ra onBind?

Trả lời

8

1 Tạo một giao diện thực hiện kê khai tất cả các phương pháp chữ ký mà bạn muốn gọi từ một Hoạt động:

public interface ILocationService { 
    public void StartListenLocation(Location location); 
} 

2 Làm chất kết dính của bạn thực hiện ILocaionService và xác định cơ thể phương pháp thực tế:

public class MyBinder extends Binder implements ILocationService { 
    ... ... 

    public void StartListenLocation(Location location) { 
    // implement your method properly 
    } 

    ... ... 
} 

3 Trong hoạt động liên kết với dịch vụ, hãy tham chiếu giao dịch của bạn bằng giao diện:

... ... 

ILocationService mService; // communication is handled via Binder not the actual service class. 

private ServiceConnection mConnection = new ServiceConnection() { 

    public void onServiceConnected(ComponentName className, IBinder service) { 
    mService = (ILocationService) service;  
    } 

    ... ... 
}; 

... ... 

// At some point if you need call service method with parameter: 
Location location = new Location(); 
mService.StartListenLocation(location); 

Tất cả các liên lạc (tức là phương thức gọi đến dịch vụ của bạn) nên được xử lý và thực hiện thông qua lớp binder khởi tạo và trả về trong ServiceConnection.onServiceConnected(), không phải lớp dịch vụ thực tế (binder.getService() là không cần thiết). Đây là cách liên kết dịch vụ liên kết được thiết kế để hoạt động trong API.

Lưu ý rằng bindService() là một cuộc gọi không đồng bộ. Sẽ có một sự chậm trễ sau khi bạn gọi bindService() và trước khi ServiceConnection.onServiceConnected() gọi lại được tham gia bởi hệ thống. Vì vậy, nơi tốt nhất để thực hiện phương thức dịch vụ là ngay sau khi mService được khởi tạo trong phương thức ServiceConnection.onServiceConnected().

Hy vọng điều này sẽ hữu ích.

+0

Cảm ơn cho câu trả lời . Tôi gặp phải một vấn đề khác sau này, có thể bạn biết cách giải quyết nó: http://stackoverflow.com/questions/9956601/android-set-and-get-services-variable-in-different-activities –

+0

@yorkw "Đây là cách liên kết dịch vụ liên kết được thiết kế để hoạt động trong API "- không phải tôi nghi ngờ bạn là chính xác, nhưng bạn có liên kết tới một số tài liệu Android chính thức nơi tôi có thể đọc thêm về điều này không? – DuneCat

+2

@DuneCat, tôi đồng ý rằng tuyên bố không hoàn toàn chính xác, nó thực sự được tham chiếu một trong những cách được đề xuất mà Google đề xuất để triển khai dịch vụ bị ràng buộc, xem [tại đây] (http://developer.android.com/guide/components/bound -services.html # Binder) để biết thêm chi tiết. – yorkw

0

Theo phiên này http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html

Một cách để gửi dữ liệu đến một dịch vụ là bằng cách sử dụng một cơ sở dữ liệu chứa các cột pid (quá trình id), dữ liệu, tình trạng nơi tình trạng có thể được đọc, READY, ràng buộc và như vậy, khi dịch vụ được tải nó đọc bảng được lấp đầy bởi hoạt động gọi và có thể bị xóa khi hoàn tất, cách khác được biểu thị là AIDL như được chỉ ra trong câu trả lời trước, chọn theo ứng dụng của bạn.

26

Bạn có thể vượt qua các tham số trong phương pháp đơn giản này: -

Intent serviceIntent = new Intent(this,ListenLocationService.class); 
    serviceIntent.putExtra("From", "Main"); 
    startService(serviceIntent); 

và nhận được các tham số trong phương pháp onStart của lớp dịch vụ của bạn

@Override 
public void onStart(Intent intent, int startId) { 
    super.onStart(intent, startId); 
    Bundle extras = intent.getExtras(); 
if(extras == null) 
    Log.d("Service","null"); 
else 
{ 
    Log.d("Service","not null"); 
    String from = (String) extras.get("From"); 
    if(from.equalsIgnoreCase("Main")) 
     StartListenLocation(); 
} 

} 

Enjoy :)

+2

Đây là cách để chuyển các tham số cho phương thức onBind, như được yêu cầu. @yorkw có giải pháp chung tốt để gọi Hoạt động từ Dịch vụ. –

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