【问题标题】:Android: Communication between activity and serviceAndroid:活动和服务之间的通信
【发布时间】:2015-03-29 22:11:00
【问题描述】:

我对 Android 有点陌生,所以请帮助我理解这一点。 在从 android 开发者网站上阅读服务时,我发现这一段我无法举出一个例子:

如果服务不提供绑定,则使用 startService() 传递的意图是应用程序组件和服务之间唯一的通信方式。但是,如果您希望服务发回结果,则启动服务的客户端可以为广播创建 PendingIntent(使用 getBroadcast())并将其传递给启动服务的 Intent 中的服务。然后服务可以使用广播来传递结果。

我知道还有其他方法可以将结果发送回活动,但我认为上面解释的逻辑比任何其他方法都简单。请通过示例帮助我理解这一点。

【问题讨论】:

    标签: android


    【解决方案1】:

    我们可以使用BroadcastReceiverResultReceiver 来接收来自Service 的结果。这一次,我想指导你使用ResultReceiver

    首先,创建一个类以在您的活动中接收结果并扩展ResultReceiver

    private class MyReceiver extends ResultReceiver {
        public MyReceiver(Handler handler) {
            super(handler);
        }
    
        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            super.onReceiveResult(resultCode, resultData);
            /*
            * We can get the type of data passed from Service to Activity:
            * int --> getInt("key")
            * String --> getString("key")
            * boolean --> getBoolean("key")
            * /
            if (resultCode == MyService.RUNNING) {
                String str = resultData.getString("dataStringKey"); // get information within the key, i.e. "dataString"
                myTextView.setText(str); // set the text to get the data received
            }
    
            if (resultCode == MyService.SERVICE_STOPPED) {
                // do something, such as get data received with the key
            }
        }
    }
    

    在你的Service

    public static final int RUNNING = 0;
    public static final int SERVICE_DESTROYED = 1;
    private ResultReceiver receiver;
    private Bundle resultData;
    private int status;
    
    @Override
    public void onCreate() {
        super.onCreate();
        resultData = new Bundle();
        status = RUNNING;
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        receiver = intent.getParcelableExtra("receiver");
        String dataFromActivity = intent.getStringExtra("text");
        /*
        * send result/information to activity, also we can put:
        * int --> putInt("key", value)
        * boolean --> putBoolean("key", value)
        * String --> putString("key", "My string.")
        * /
        resultData.putString("dataStringKey", "Hi, this is a String data.");
        receiver.send(status, resultData);
    
        return Service.START_NOT_STICKY;
    }
    
    @Override
    public void onDestroy() {
        status = SERVICE_DESTROYED;
        receiver.send(status, resultData);
        super.onDestroy();
    }
    

    当你触发Service:

    Intent intent = new Intent(MyActivity.this, MyService.class);
    intent.putExtra("text", "Text to be passed to Service.");
    intent.putExtra("receiver", new MyReceiver(new Handler()));
    this.startService(intent);
    

    【讨论】:

      【解决方案2】:

      使用Intent 将数据从您的Activity 发送到Service,并使用LocalBroadcastManager 将数据从您的Service 发送到Activity。

      这是关于如何使用 LocalBroadcastManager 的example

      public class LocalBroadcastExampleActivity extends Activity {
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              // TODO Auto-generated method stub
              super.onCreate(savedInstanceState);
              setContentView(R.layout.log_list);
      
              Button buttonStartService = (Button)findViewById(R.id.button_ok);
              buttonStartService.setOnClickListener(new View.OnClickListener() {
      
                  @Override
                  public void onClick(View v) {
                      // TODO Auto-generated method stub
                      //Register MessageService in Manifest to work
                      Intent intent = new Intent(LocalBroadcastExampleActivity.this, MessageService.class);
                       intent.putExtra("mydatakey", myString);  // <--- set data to send to service
                      startService(new Intent(LocalBroadcastExampleActivity.this, MessageService.class));
                  }
              });
      
          }
      
          @Override
          protected void onPause() {
              // Unregister since the activity is paused.
              LocalBroadcastManager.getInstance(this).unregisterReceiver(
                      mMessageReceiver);
              super.onPause();
          }
      
          @Override
          protected void onResume() {
              // Register to receive messages.
              // We are registering an observer (mMessageReceiver) to receive Intents
              // with actions named "custom-event-name".
              LocalBroadcastManager.getInstance(this).registerReceiver(
                      mMessageReceiver, new IntentFilter("custom-event-name"));
              super.onResume();
          }
      
          // Our handler for received Intents. This will be called whenever an Intent
          // with an action named "custom-event-name" is broadcasted.
          private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
              @Override
              public void onReceive(Context context, Intent intent) {
                  // TODO Auto-generated method stub
                  // Get extra data included in the Intent
                  String message = intent.getStringExtra("message");
                  Log.d("receiver", "Got message: " + message);
              }
          };
      
          public class MessageService extends Service {
      
              @Override
              public IBinder onBind(Intent intent) {
                  // TODO Auto-generated method stub
                  return null;
              }
      
              @Override
              public int onStartCommand(Intent intent, int flags, int startId) {
                  // TODO Auto-generated method stub
                  String mydata = intent.getStringExtra("mydatakey"); // <--- retrieve data sent from Service
                  sendMessage();
                  return super.onStartCommand(intent, flags, startId);
              }
      
              // Send an Intent with an action named "custom-event-name". The Intent
              // sent should
              // be received by the ReceiverActivity.
              private void sendMessage() {
                  Log.d("sender", "Broadcasting message");
                  Intent intent = new Intent("custom-event-name");
                  // You can also include some extra data.
                  intent.putExtra("message", "This is my message!");
                  LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
              }
      
          }
      
      }
      

      但就我而言,我更喜欢使用事件总线库,例如 EventBusOtto,它们更易于使用且耗时更少。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多