2013-02-15 50 views
25

Có một dịch vụ lắng nghe một số giọng nói. Nếu giọng nói khớp với chuỗi, một phương thức nhất định sẽ được gọi trong đối tượng dịch vụ.Cách gọi phương thức hoạt động từ một dịch vụ

public class SpeechActivationService extends Service { 

    public static Intent makeStartServiceIntent(Context pContext){  

     return new Intent(pContext, SpeechActivationService.class); 
    } 

    //... 

    public void onMatch(){ 
     Log.d(TAG, "voice matches word"); 
    } 

    //... 
} 

Đây là cách tôi bắt đầu dịch vụ trong hoạt động của tôi:

Intent i = SpeechActivationService.makeStartServiceIntent(this); 
startService(i); 

Từ phương pháp dịch vụ này, làm thế nào tôi có thể gọi một phương pháp mà nằm trong các đối tượng hoạt động? Tôi không muốn truy cập từ hoạt động để phục vụ, nhưng từ dịch vụ đến hoạt động. Tôi đã đọc về xử lý và các đài truyền hình nhưng không thể tìm/hiểu bất kỳ ví dụ nào. Bất kỳ ý tưởng?

+0

Liệu phương pháp này phải trong lớp Hoạt động, hoặc bạn có thể di chuyển nó vào một lớp tiện ích? –

+0

Tôi muốn cập nhật giao diện người dùng vì vậy tôi nghĩ rằng nó phải ở trong lớp hoạt động –

Trả lời

2

Có nhiều cách khác nhau để đạt được điều này. Một trong số họ sử dụng các lớp học HandlerMessanger. Ý tưởng của phương pháp là để vượt qua đối tượng Handler từ Activity đến Service. Mỗi lần Service muốn gọi một số phương thức của Activity, nó chỉ gửi MessageActivity xử lý bằng cách nào đó.

Hoạt động:

public class MyActivity extends Activity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     final Handler handler = new Handler() { 
      @Override 
      public void handleMessage(Message msg) { 
       showToast(msg.what); 
      } 
     }; 

     final Intent intent = new Intent(this, MyService.class); 
     final Messenger messenger = new Messenger(handler); 

     intent.putExtra("messenger", messenger); 
     startService(intent); 
    } 

    private void showToast(int messageId) { 
     Toast.makeText(this, "Message " + messageId, Toast.LENGTH_SHORT).show(); 
    } 
} 

dịch vụ:

public class MyService extends Service { 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     if (intent != null) { 
      final Messenger messenger = (Messenger) intent.getParcelableExtra("messenger"); 
      final Message message = Message.obtain(null, 1234); 

      try { 
       messenger.send(message); 
      } catch (RemoteException exception) { 
       exception.printStackTrace(); 
      } 
     } 

     return START_NOT_STICKY; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 
} 
+0

Dịch vụ của tôi mở rộng từ dịch vụ chứ không phải IntentService –

+0

Bạn cũng có thể sử dụng 'Dịch vụ'. Mã này chỉ cho thấy ý tưởng. Tôi đã cập nhật câu trả lời của mình và giờ nó sử dụng 'Dịch vụ' thay vì' IntentService' –

+0

+1 Cảm ơn bạn, tôi đã quản lý nó với bộ thu phát sóng http://inchoo.net/mobile-development/android-development/broadcast-receiver-từ -activity/ –

54

Giả sử dịch vụ và hoạt động của bạn đang ở trong cùng một gói (tức là cùng một ứng dụng), bạn có thể sử dụng LocalBroadcastManager như sau:

Trong Dịch vụ của bạn:

// Send an Intent with an action named "my-event". 
private void sendMessage() { 
    Intent intent = new Intent("my-event"); 
    // add data 
    intent.putExtra("message", "data"); 
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent); 
} 

Trong hoạt động của bạn:

@Override 
public void onResume() { 
    super.onResume(); 

    // Register mMessageReceiver to receive messages. 
    LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, 
     new IntentFilter("my-event")); 
} 

// handler for received Intents for the "my-event" event 
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
    // Extract data included in the Intent 
    String message = intent.getStringExtra("message"); 
    Log.d("receiver", "Got message: " + message); 
    } 
}; 

@Override 
protected void onPause() { 
    // Unregister since the activity is not visible 
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); 
    super.onPause(); 
} 

Từ phần 7.3 của liên kết @ Ascorbin của: http://www.vogella.com/tutorials/AndroidBroadcastReceiver/article.html#ownreceiver_localbroadcastmanager

+3

Nó hoạt động như một say mê, TY! –

+1

Điều đó hoàn toàn tuyệt vời, cảm ơn người đàn ông bạn đã cứu tôi – Ale

+1

Cảm ơn Tony! Câu trả lời tuyệt vời – Nickmccomb

0

Sau khi một số nghiên cứu tôi thấy timings sau trong trường hợp của tôi để gửi và nhận phát sóng. Tôi có dịch vụ trong cùng một quy trình.

sendBroadcast (Không khuyến khích nếu cả hai thành phần là trong cùng một quá trình) 34 giây

LocalBroadcastManager.getInstance (this).sendBroadcast (ý định); gần 30 giây

Thực hiện sử dụng AIDL và RemoteCallbackList Sẽ làm việc cho cùng một quy trình hay quá trình khác nhau

Trong dịch vụ của bạn

public final RemoteCallbackList<ICallBackAidl> mDMCallbacks = new RemoteCallbackList<ICallBackAidl>(); 

public void registerDMCallback(ICallBackAidl cb) { 
    Logger.d(LOG_TAG, "registerDMCallback " + cb); 
    if (cb != null) 
     mDMCallbacks.register(cb); 
} 

Khi bạn cần gọi phương pháp trong Application/Acitvity từ dịch vụ

public void callMehodsInApplication() { 
    final int N = mDMCallbacks.beginBroadcast(); 
    for (int i = 0; i < N; i++) { 
     try { 
      mDMCallbacks.getBroadcastItem(i).method1(); 
     } catch (RemoteException e) { 
      e.printStackTrace(); 
     } 
    } 
    mDMCallbacks.finishBroadcast(); 
} 

Trong lớp học cũ của bạn ứng dụng hoặc hoạt động chăm sóc.

private ISyncmlServiceDMCallback mCallback = new ISyncmlServiceDMCallback.Stub() { 
// Implement callback methods here 
    public void method1() { 
     // Service can call this method 
    } 
} 

public void onServiceConnected(ComponentName name, IBinder service) { 
     svc.LocalBinder binder = (svc.LocalBinder) service; 
     mSvc = binder.getService(); 
     mSvc.registerDMCallback(mCallback); 
} 

Gọi theo cách này là gần như tức thời từ phát thanh truyền hình và nhận được so với cùng quá trình

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