Android service与Activity通信

本文详细介绍了Android中Service与Activity之间的通信方式,包括使用回调接口、广播接收者以及Handler和Messenger。重点讲解了通过定义回调接口实现Activity与Service的互调,以及在Service中如何利用Handler向Activity传递消息。这两种方法为Android组件间的通信提供了灵活的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.eoeandroid.com/thread-334433-1-1.html

我们都知道,Activity可以与Service进行绑定,绑定过后就可以方便调用Service中的方法了,既然Activity可以调用Service的方法就说明Activity可以向Service中传递信息,那么Service如何向Activity传递信息呢?
一,如果Activity调用Service的方法后能获取返回值,那Activity想什么时候从Service中获取信息就什么时候调用Service中的方法。
  但是,这种方法有局限性,因为Activity不知道Service中的信息什么时候更新,不能被动的接收信息。

二,利用广播接收者可以解决方法1的局限性,当Service中信息有更新时就发送一个广播到Activity中,Activity中注册一个广播接收者来接收广播,以此来更新Activity中的信息。但是有个疑问,假设频繁的发送广播会不会资源消耗大。

三,写一个回调接口
具体步骤如下:
1.先写一个用来做回调的接口
public interface ICount {
     void count(int val);
}
2.Service类
public class CountService extends Service {
     private int val = 0;

     public void startCount(ICount iCount){ // 调用CountActivity,因为CountActivity实现了ICount
          // do something ...
          val ++;
          iCount.count(val);
     }
}
3.Activity类
注:省略了绑定CountService的代码
public class CountActivity extends Activity implements ICount {
     @Override
     protected void onCreate(){
         // do something ...
         startCount(this); // 调用CountService对象的startCount()方法,并把自己传了进入,这样的话CountService对象就能调用自己的方法了
     }
     
     @Override    
     void count(int val){
         // update UI
     }
}

小结:
       其实第三种方法是Activity与Service的互调,显示CountActivity调用了CountService的startCount()方法,紧接着CountService在startCount()方法中又调用了CountActivity的count()方法,并把val值传了进入。
       关键点在于接口ICount,ICount把传值(即通信)功能封装起来了,不管谁实现了ICount接口,谁都能通过回调方法count()来接收val值。这就是ICount接口的意义。
       回调,回调,就是我调用你的方法,并把”我“这个对象传给你,你又使用”我“这个对象来调用我的方法,这就是回调。



四、利用Handler

http://www.mamicode.com/info-detail-459214.html

通过之前的学习,我们知道了在主线程中声明一个handler实例并实现了消息的处理方法之后,我可以在子线程中用此实例向主线程发消息,在处理方法中获取消息并更新UI。

那么,如果我们想用handler在service中向activity文件传递消息呢?在这里提供了两种方法

方法一:

在想接收消息的Activity中,把handler实例声明为静态的公用的,即 public static Handler handler;

由于为公用静态的成员变量,那么就可以以 activityname.handler.sendmessage()方式来发送消息了

 

方法二:

在service中新建一个方法,传入activity的上下文,在service中定义一个静态的目标activity类成员变量,将得到的上下文赋予成员变量,并通过新定义的这个方法来启动服务。

例子如下

  private static foregroundactivity activity;

    public static void onstar(Context c)
    {
        activity = (foregroundactivity) c;
        Intent intent = new Intent(c,foregroundservice.class);
        activity.startService(intent);
    }
??????

http://www.cnblogs.com/lee0oo0/articles/3149551.html

5.5. Handler and Messenger

If the service should be communicating back to the activity it can receive an object of type Messengervia the Intent data it receives from the activity. If the Messenger is bound to a Handler in theactivity the service can send objects of type Message to the activity.

Messenger is parcelable, which means it can be passed to another process and you can use this object to send Messages to the Handler in the activity.

Messenger provides also the method getBinder() which allows to pass a Messenger to theactivity. The activity can therefore send Messages to the service.


http://blog.youkuaiyun.com/a_asinceo/article/details/7961701

其实实现IPC的方式,还有AIDL,但推荐使用Messenger,有两点好处:


      1. 使用Messenger方式比使用AIDL的方式,实现起来要简单很多


      2. 使用Messenger时,所有从Activity传过来的消息都会排在一个队列里,不会同时请求Service,所以是线程安全的。如果你的程序就是要多线程去访问Service,就可以用AIDL,不然最好使用Messenger的方式。


  不过,其实Messenger底层用的就是AIDL实现的,看一下实现方式,先看Service的代码:
Java代码 
public class MessengerService extends Service {   
    /** 用于Handler里的消息类型 */  
    static final int MSG_SAY_HELLO = 1;   
  
    /**  
     * 在Service处理Activity传过来消息的Handler  
     */  
    class IncomingHandler extends Handler {   
        @Override  
        public void handleMessage(Message msg) {   
            switch (msg.what) {   
                case MSG_SAY_HELLO:   
                    Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();   
                    break;   
                default:   
                    super.handleMessage(msg);   
            }   
        }   
    }   
  
    /**  
     * 这个Messenger可以关联到Service里的Handler,Activity用这个对象发送Message给Service,Service通过Handler进行处理。  
     */  
    final Messenger mMessenger = new Messenger(new IncomingHandler());   
  
    /**  
     * 当Activity绑定Service的时候,通过这个方法返回一个IBinder,Activity用这个IBinder创建出的Messenger,就可以与Service的Handler进行通信了  
     */  
    @Override  
    public IBinder onBind(Intent intent) {   
        Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();   
        return mMessenger.getBinder();   
    }   
}  


 再看一下Activity的代码:
Java代码 
public class ActivityMessenger extends Activity {   
    /** 向Service发送Message的Messenger对象 */  
    Messenger mService = null;   
  
    /** 判断有没有绑定Service */  
    boolean mBound;   
  
    private ServiceConnection mConnection = new ServiceConnection() {   
        public void onServiceConnected(ComponentName className, IBinder service) {   
            // Activity已经绑定了Service   
            // 通过参数service来创建Messenger对象,这个对象可以向Service发送Message,与Service进行通信   
            mService = new Messenger(service);   
            mBound = true;   
        }   
  
        public void onServiceDisconnected(ComponentName className) {   
            mService = null;   
            mBound = false;   
        }   
    };   
  
    public void sayHello(View v) {   
        if (!mBound) return;   
        // 向Service发送一个Message   
        Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);   
        try {   
            mService.send(msg);   
        } catch (RemoteException e) {   
            e.printStackTrace();   
        }   
    }   
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {   
        super.onCreate(savedInstanceState);   
        setContentView(R.layout.main);   
    }   
  
    @Override  
    protected void onStart() {   
        super.onStart();   
        // 绑定Service   
        bindService(new Intent(this, MessengerService.class), mConnection,   
            Context.BIND_AUTO_CREATE);   
    }   
  
    @Override  
    protected void onStop() {   
        super.onStop();   
        // 解绑   
        if (mBound) {   
            unbindService(mConnection);   
            mBound = false;   
        }   
    }   
}  


 注意:以上写的代码只能实现从Activity向Service发送消息,如果想从Service向Activity发送消息,只要把代码反过来写就可以了。


### AndroidService Activity通信机制 在 Android 开发中,`Service` 和 `Activity` 是两个重要的组件。它们可以通过多种方式进行交互和通信。以下是几种常见的通信方式及其示例。 #### 1. 使用 `startService()` 启动服务并传递数据 通过调用 `startService()` 方法可以启动一个后台服务,并向其发送消息或指令。这种方式适用于不需要长期绑定的服务场景。 - **Activity 调用代码** ```java Intent intent = new Intent(this, MyService.class); intent.putExtra("key", "value"); startService(intent); // 启动服务并向其传递数据 ``` - **Service 接收代码** ```java @Override public int onStartCommand(Intent intent, int flags, int startId) { String value = intent.getStringExtra("key"); // 获取来自Activity的数据 Log.d("MyService", "Received data from Activity: " + value); return START_STICKY; } ``` 上述方法展示了如何通过 `Intent` 将数据从 `Activity` 发送到 `Service`[^1]。 --- #### 2. 使用 `bindService()` 绑定到服务并通信 当需要更紧密的耦合关系时,可以使用 `bindService()` 来建立连接。这通常用于需要频繁交互的情况。 - **定义接口供回调使用** ```java // 定义AIDL或者Binder对象作为桥梁 public class LocalBinder extends Binder { public MyService getService() { return MyService.this; // 返回当前Service实例 } } private final IBinder binder = new LocalBinder(); ``` - **重写 `onBind()` 方法返回 Binder 对象** ```java @Override public IBinder onBind(Intent intent) { return binder; // 提供给客户端访问 } ``` - **Activity 链接至 Service 并获取实例** ```java private MyService myBoundService; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { LocalBinder localBinder = (LocalBinder) service; myBoundService = localBinder.getService(); // 得到Service实例 } @Override public void onServiceDisconnected(ComponentName name) {} }; Intent bindIntent = new Intent(this, MyService.class); bindService(bindIntent, connection, Context.BIND_AUTO_CREATE); // 建立链接 ``` 此部分描述了如何利用 `bindService()` 实现双向通信以及资源共享的功能[^3]。 --- #### 3. 结合 `Messenger` 或者 AIDL 实现跨进程通信 如果目标是支持多线程操作或者是远程过程调用(RPC),则可以选择基于 `Handler` 的 `Messenger` 类型或是更为复杂的 AIDL 文件来完成 IPC(Inter-process Communication)。这里仅展示简单的 Messenger 方案: - **创建 Handler 处理消息队列** ```java class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SET_VALUE: int newValue = msg.arg1; break; default: super.handleMessage(msg); } } } final Messenger messenger = new Messenger(new IncomingHandler()); ``` - **注册该信使于 Service 内部** ```java @Override public IBinder onBind(Intent intent) { return messenger.getBinder(); // 替代传统binder模式 } ``` 以上片段说明了借助 `Messenger` 可简化某些特定场合下对于复杂同步逻辑的需求[^2]。 --- ### 总结 综上所述,在实际开发过程中可以根据具体需求选取合适的方案来进行 Android 应用内的组件间通讯工作。无论是单次性的任务委派还是持续性的状态共享都可以找到对应的解决办法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值