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 Messenger
via 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.
A 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
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发送消息,只要把代码反过来写就可以了。