如何从一个服务调用一个方法中活动(How to call a method in activity

2019-07-19 23:44发布

有监听一些语音服务。 如果语音字符串匹配某种方法在服务对象调用。

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");
     }

     //...
}

这是我开始在我的活动的服务:

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

从这项服务中的方法,我怎么可以调用驻留在活动对象的方法? 我不想从活动服务,但是从服务活动的访问。 我已阅读有关处理程序和广播,但找不到/明白任何例子。 有任何想法吗?

Answer 1:

我会登记在活动一个BroadcastReceiver,并从服务发送一个Intent给它。 请参见本教程: http://www.vogella.com/articles/AndroidBroadcastReceiver/article.html它看起来有点长,但你要学习如何使用反正那些;)



Answer 2:

假设你的服务和活动都在同一个包(即在同一应用程序),你可以使用LocalBroadcastManager如下:

在您的服务:

// 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);
}

在您的活动:

@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();
}

从@维他命C的链接的第7.3节: http://www.vogella.com/tutorials/AndroidBroadcastReceiver/article.html#ownreceiver_localbroadcastmanager



Answer 3:

有许多不同的方式来实现这一目标。 其中一人用HandlerMessanger类。 该方法的想法是通过Handler从对象ActivityService 。 每次Service要调用的一些方法Activity ,它只是发送MessageActivity处理它以某种方式。

活动:

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();
    }
}

服务:

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;
    }
}


Answer 4:

经过一番研究,我发现在我的情况下定时发送和接收广播。 我有同样的流程服务。

sendBroadcast(不推荐如果两个部件在相同的处理)34秒

LocalBroadcastManager.getInstance(本).sendBroadcast(意向); 接近30秒

使用AIDL和RemoteCallbackList实现将工作的过程相同或不同的过程

在您服务

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);
}

当您需要调用从服务应用程序/ Acitvity方法

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();
}

在你的类扩展应用程序或活动。

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);
 }

调用此方法是从广播几乎是瞬间,并从同一个进程接收



文章来源: How to call a method in activity from a service