Service通信(service介绍之二)

在介绍Service通信前,我说聊一个东西,前台Service

前台Service和普通Service最大的区别就在于,它会一直有一个正在运行的图标在系统的状态栏显示,下拉状态栏后可以看到更加详细的信息,非常类似于通知的效果。当然有时候你也可能不仅仅是为了防止Service被回收才使用前台Service,有些项目由于特殊的需求会要求必须使用前台Service,比如说墨迹天气,它的Service在后台更新天气数据的同时,还会在系统状态栏一直显示当前天气的信息。

public class MyService extends Service {  
  
    public static final String TAG = "MyService";  
  
    private MyBinder mBinder = new MyBinder();  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        Notification notification = new Notification(R.drawable.ic_launcher,  
                "有通知到来", System.currentTimeMillis());  
        Intent notificationIntent = new Intent(this, MainActivity.class);  
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,  
                notificationIntent, 0);  
        notification.setLatestEventInfo(this, "这是通知的标题", "这是通知的内容",  
                pendingIntent);  
        startForeground(1, notification);  
        Log.d(TAG, "onCreate() executed");  
    }  
  
    .........  
  
}  

在使用android 4.1系统的时候,发现在手机休眠一段时间后(1-2小时),后台运行的服务被强行kill掉,有可能是系统回收内存的一种机制,要想避免这种情况可以通过startForeground让服务前台运行,当stopservice的时候通过stopForeground去掉。


下面,我们可以聊通信了。

默认情况下,不错,是默认,我们建立的服务,是和程序的主线程在同一个线程中的,好的,就说到这里,这个时候,我们应该怎样处理这个之间的通信呢??

1.Intent启动时,互相启动时。

在我们启动一个服务的时候,可以使用startService(Intent intent),这种格式。聪明的你应该知道,哈哈哈,Intent可以存储数据的,那么这样,我们就可以把数据扔过去了。在Service的onStartCommand中,就有可以使用的回调Intent参数,我们就可以使用参数了。

同样,在我们用Service启动一个Actvity时,也可以用PendingIntent来传输数据。这种方法是很原始的。


2.通过广播

广播,像是在系统中的公共服务,他可以时刻侦听和发送指令。

之前,我认为广播,就像服务器运行中通信所运行的功能。实际上,还有别的。

这里代码就不贴了。

我看到过这样一个实例,作者动态register一个广播接受器。然后在receiver的实现类中,直接用---控件.方法。
我纳闷的是,在广播接受器中这样写能不能调用得到。


3.Binder,这个东西,可以跨越进程,更不用说线程了。

 这个是新家伙,看看安卓文档的介绍吧。
Base class for a remotable object, the core part of a lightweight remote procedure call mechanism defined by IBinder. This class is an implementation of IBinder that provides the standard support creating a local implementation of such an object. 
轻量级的远程类处理器,是对IBinder借口的实现。
Most developers will not implement this class directly, instead using the aidl tool to describe the desired interface, having it generate the appropriate Binder subclass. You can, however, derive directly from Binder to implement your own custom RPC protocol or simply instantiate a raw Binder object directly to use as a token that can be shared across processes.
这里看到了没,AIDl,这个的全称是Android Interface Developnment Language。

下面,简单介绍一下Binder机制,android系统为了有利于管理进程线程的通信,为了有利于开发者进行开发,加入了这个Binder机制。利用Binder可以调用系统服务(系统服务肯定不会和Activity在一个进程中)。Binder架构机制的核心是Binder驱动,Binder驱动运行在Linux内核层面,在内存上有一块自己的空间。在这个架构中,同样还有服务端Binder对象,和客户端的Binder实例引用。在Service开始服务的时候,我们可以选择是否开启Binder,在服务器开始运行的时候,Binder驱动会自己创建一个mRemot对象,负责信息的传送。通过获取含有Binder对象的service在Binder驱动中的mRemot引用,来调用服务。

详细一点的,可以看这个:http://www.linuxidc.com/Linux/2012-07/66195.htm

简单的说,我们经常把进程比喻成车道,那么Binder,我感觉,就像是时刻横在道路上的镜子,一个服务,接受了镜子,那么镜子就有了它的像,就像是对他引用的一个对象,我们在自己的车上,通过一个通道,就可以获取这个像,并转型成所需要的那个像。

(1),在服务Service类中,建立Binder:(实际上,下面这些,可以写的简单点,一句话就行了。)
public IBinder onBind(Intent intent) {
return new MsgBinder();//通过一个方法,返回一个Binder实例。
}
public class MsgBinder extends Binder{//继承和创建一个Binder对象,在这个对象实现的过程中,Binder机制中的Binder驱动就开始建立引用了。
public MsgService getService(){
return MsgService.this;//通过一个方法,返回对象。
}
}

(2),在客户端

bindService(Intent service, ServiceConnection conn,int flags);//首先,肯定是粘上一个服务了。其中有两个参数
//一个是ServiceConnection    这个对象连接的实例,当服务启动后,这个对象会在本地线程调用。
//flags    肯定就是Context.BIND_AUTO_CREATE。
ServiceConnection conn = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
}
public void onServiceConnected(ComponentName name, IBinderservice) {
myService = ((myService.MsgBinder)service).getService();//返回一个MsgService对象,getService这个方法是Binder所定义的。
}
};

取得了myService 这个名字(在复杂数据类型中,数据的名字就是内存的引用,这个是常识了),你就可以随意调用了。你可以在服务端,设几个变量值,这个引用的也方便。
4.Binder 的另外一种使用。

实际上,我们在ServiceConnection中,可以包含Activity中应该有的操作。不解释,直接上代码:摘取关键部分:

private OnProgressListener onProgressListener;
public void setOnProgressListener(OnProgressListener onProgressListener) {
this.onProgressListener = onProgressListener;
}
//上面的一个对象,一个方法,放在Service的类里面。

然后在使用的时候,或者可以说在ServiceConnection,得到这个服务后,我们就可以给这个Service对象,加上侦听器。ps:press定义完全。



在这里,基本把Service的通信差不多了。无论时广播,还是Binder,都是在底层部分,跨越时间了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值