Android中的 Service 是一个优先级比较高的 系统组件 ,他不是一个独立的进程也不是一个线程 !

文档中有说明:

A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.
A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).
Service 没有用户界面,可以认为是在系统中永久运行的组件 .(这个是一个非常重要的特性 )

( 如果不是调用 stopService,unbindService,或者 stopSelf() 系统会让他一直运行下去,就算因为没有资源暂时停止,稍后也会再次运行,就算手动停止所在进程,系统也会重新启动该服务.)

启动:

可以使用 Context.startService(Intent) 或者 Context.bindService(Intent intent, ServiceConnection connn, int flags); 启动.

停止:

使用Context.stopService(Intent) 或者 Context.unBindService(ServiceConnection); 停止 . 但是必须所有服务连接关闭之后Service才能真正停止 !

使用准备: 需要在 AndroidManifest.xml中注册你的 Service

比如: ( 简单点的) <service android:name =".LocalService"/>


再如: ( 复杂点的):

<service android:name =".MyService" ------名字这是必须的

android:process =":service" ------进程名
>
<intent-filter>
<!-- AIDL完整路径名。必须指明,客户端能够通过AIDL类名查找到它的实现类 -->
<action android:name="com.en.demo.service.remoteServices.MyServiceBinder" />
</intent-filter>
</service>

进程内使用:

可以通过startService(Intent);来启动 service 这个方法可以使用在一些自动执行的服务中,比如自动检测手机信息,自动检测软件版本等.

通过 boolean android.content.ContextWrapper.bindService(Intent service, ServiceConnection conn, int flags) 可以绑定服务( 绑定是什么东东? 我的理解就只是给你一个对象 ,让你可以找到 你的服务的对象 ,这样可以调用服务的功能 ) 绑定之后就可以 调用啦.

其中参数 : Intent 就是和startService一样都是需要告诉系统启动那个服务

ServiceConnection 就是一个连接成功调用的接口 当服务启动成功,系统将调用这个接口的 onServiceConnected (ComponentName name, IBinder service)方法 这个方法传入了可以 找到服务的 参数

flags 是标记那个调用者的

为什么说 这样可以找到服务呢?

如果我们继承了Service 可以看到 Service中有一个 未实现的方法: public IBinder onBind(Intent intent) ;

可以看到这里返回的是一个 IBinder 和前面 onServiceConnected传入的参数一样.一切就是从这里开始做文章的.

这是我的例子中的一个服务:

public class LocalService extends Service {


class MyBinder extends Binder{ // Binder 是 IBinder 接口的一个实现可以让我们不必写出全部抽象方法
public Service getService(){
return LocalService.this;
}
}

@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}

/**** 这个服务的 一些功能 ( 略 )***/ }

从这里开始我们可以看到 MyBinder 可以返回我们的 Service 对象.

从调用那里就可以这样做

// 创建本地调用对象
private ServiceConnection localConnection = new ServiceConnection() {

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
/* 获得对象 */
localService = (LocalService) ((LocalService.MyBinder) service)
.getService(); // 这里我们就可以获得 这个服务的引用了.
System.out.println("Bind local Service Success: " + localService);

}
@Override
public void onServiceDisconnected(ComponentName name) {
localService = null;
}
};


但是这样引用了有什么用 ? 我的例子中运行界面是 :

这里点击 " 获取名字 "按钮时候的代码是:

public void onClick(View v) {
try {
if (onBind) {
showResult.setText("本地服务->获取名字: "
+ localService.getName()); // getName 是一个功能
} else {
Toast.makeText(StartActivity.this, "请先绑定服务 ",
Toast.LENGTH_SHORT).show();
}

} catch (RemoteException e) {
e.printStackTrace();
}

}

我们就可以直接使用 服务的实例进行工作了.

具体功能可以看工程里面的代码.

跨进程服务:

我们可以调用系统提供的服务,比如

ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE)); // 这里 获得一个 系统服务am.restartPackage(getPackageName());

这样可以关闭当前进程


我们的服务也可以为别人的程序服务,只要我们实现了接口,并在androidMainfast.xml中写清楚了就可以了

更重要的我们需要了解一个 AIDL ( android interface definition language )接口描述语言

我们不可能无缘无故自己的程序中写一个 interface 然后就说那是某个服务的接口吧.我们怎么样才知道有这个接口呢? aidl 提供了这个功能.

提供服务端:

当我们创建一个 aidl 文件 并在其中写入我们的接口的时候,adt 会自动生成对应的接口文件 .Java文件这样我们在我们的服务中实现这个接口就可以了.


比如我这个例子中是在一个 RemoteServices的工程中 实现提供了一个服务,

这个服务提供了那些对外服务? 我们就在 MyServiceBinder .aidl这个文件中描述了.

aidl 这个文件使用的语法与 java一样
package com.en.demo.service.remoteServices;

//import com.en.demo.service.MyObject;

interface MyServiceBinder{

int getAdd(int a,int b);
String getName();
void setName(String name);
//MyObject getObj();
void makeBoardCast();
}

这样在MyService中再:

用一个MyBinder类来继承
public class MyBinder extends MyServiceBinder.Stub{ //// z注意这里继承的是 Stub这个 类!!!

/* 服务提供的一些方法 */
public int getAdd(int a, int b) throws RemoteException {
return a + b;
}


public String getName() throws RemoteException {
return MyService.this.name;
}


public void setName(String name) throws RemoteException {
MyService.this.name = name;
}


public IBinder asBinder() {
return MyBinder.this;
}


public void makeBoardCast() throws RemoteException {
boardCast();
}
}


而在接收端:

MyServiceBinder remoteService ;

// 创建远程调用对象
private ServiceConnection remoteConnection = new ServiceConnection() {

public void onServiceConnected(ComponentName name, IBinder service) {
// 从远程service中获得AIDL实例化对象
remoteService = MyServiceBinder.Stub.asInterface(service);
System.out.println("Bind remote Service Success:" + remoteService);
}

public void onServiceDisconnected(ComponentName name) {
remoteService = null;
}
};

这样我们就可以调用这个服务了....

更多相关文章

  1. Android(安卓)4.0 gallery2 生成video thumbnail的过程
  2. Android网文
  3. 类似的Timer循环服务设计
  4. Android下的重力感应应用
  5. Android应用程序绑定服务(bindService)的过程源代码分析(3)
  6. Android调用系统相机拍照并保存到指定位置
  7. Android(安卓)MediaPlayer 字幕同步
  8. Android(安卓)Camera 数据流
  9. BlackBerry SIP VOIP softPhone, open source SIP client, SIP s

随机推荐

  1. Android 加载.gif格式图片
  2. Androidの通过查询电话号码或ID获取联系
  3. Android 自定义视图
  4. Android中AsyncTask异步加载
  5. Android中RecyclerView Adapter的骚操作
  6. android 修改host 文件
  7. Android EventBus使用,粘性事件postStick
  8. Android性能优化(5):APK瘦身优化
  9. Android崩溃后重启
  10. 1、android源代码下载与跟踪