介绍

Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行。另外,一个组件能够绑定到一个service与之交互(IPC机制),例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content provider)交互,所有这些活动都是在后台进行。

Service有两种状态,“启动的”和“绑定”。

使用方法

看下关于Service两张比较经典的图

简单实例

AndroidManifest.xml

   <application
android:label="@string/app_name"
android:icon="@drawable/ic_launcher"> <activity
android:name=".MyActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service android:name=".MyService"
android:enabled="true"/> <!--四大组件都要在AndroidManifest中申明一把 -->
</application>

MyActivity.java

public class MyActivity extends Activity implements View.OnClickListener, ServiceConnection {
public static String TAG = "MyActivity"; Intent intent; /**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main); Log.e(TAG, "MyActivity OnCreate");
intent = new Intent(MyActivity.this, MyService.class); findViewById(R.id.bt_startservice).setOnClickListener(this);
findViewById(R.id.bt_stopservice).setOnClickListener(this);
findViewById(R.id.bt_bindservice).setOnClickListener(this);
findViewById(R.id.bt_unbindservice).setOnClickListener(this);
}
//OnClick事件监听
public void onClick(View view) {
Log.e(TAG,"OnClick");
switch (view.getId()) {
case R.id.bt_startservice:
Log.e(TAG, "start Service");
startService(intent);
break;
case R.id.bt_stopservice:
stopService(intent);
break;
case R.id.bt_bindservice:
bindService(intent, this, Context.BIND_AUTO_CREATE);
break;
case R.id.bt_unbindservice:
unbindService(this);
break;
}
} @Override //binderService成功后回调,带过来的IBinder可用于和Activity通信
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.e(TAG, "onServiceConnected");
} @Override //在服务崩溃或被杀死导致的连接中断时被调用
public void onServiceDisconnected(ComponentName componentName) {
Log.e(TAG, "onServiceDisconnected");
}
}

MyService.java

public class MyService extends Service {
public static String TAG = "MyService"; @Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "MyService onCreate");
} @Override
public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "onStartCommand"); //用来测试Service是否在后台有运行
/*new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e(TAG, "Service is Running ...");
}
}
}).start();*/
return super.onStartCommand(intent, flags, startId);
} @Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy");
} @Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind");
return new Binder();//new一个binder对象通过onServiceConnected回调,方便通信
} @Override
public boolean onUnbind(Intent intent) {
Log.e(TAG, "onUnbind");
return super.onUnbind(intent);
} @Override //onRebind的调用时机和onUnbind的返回值有关系
public void onRebind(Intent intent) {
Log.e(TAG, "onRebind");
super.onRebind(intent);
}
}

测试结果

  1. 启动服务,停止服务

  2. 绑定服务,解绑服务

  3. 启动服务,绑定服务,解绑服务



    注意:这里最后Service是没有onDestory的

  4. 启动服务,绑定服务,解绑服务,停止服务

5. Binder使用,这个很关键

MyService.java中修改

    public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind");
return new MyBinder();
}
class MyBinder extends Binder {
public void sayHello() {
Log.e(TAG,"I am a binder, hi");
}
}

MyActivity.java中修改

    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.e(TAG, "onServiceConnected");
MyService.MyBinder binder = (MyService.MyBinder) iBinder;
((MyService.MyBinder) iBinder).sayHello();
}

然后执行:绑定服务,解绑服务

通过这个Binder,再加上Callback,可以实现对Service内部状态的监听

先定义一个接口,然后创建get与set,在onBinder方法中定义一个线程不停的发送数据

public interface Callback() {
public void onDateChanged(String data) {
}
} public void setCallback(Callback callback) {
this.callback = callback;
} public Callback getCallback() {
return callback;
}
    public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind"); running = true;//running通过service的生命周期控制
new Thread(new Runnable() {
@Override
public void run() {
while (running) {
try {
Thread.sleep(1000);
i++;
String str = "send: " + i ;
callback.onDateChanged(str);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e(TAG, "Service is Running ... ");
}
}
}).start();
return new MyBinder();
}

然后在MyBinder类中定义一个getService方法

 public MyService getSetvice() {
return MyService.this;
}

然后在onServiceConnected中

public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.e(TAG, "onServiceConnected");
MyService.MyBinder binder = (MyService.MyBinder) iBinder;
MyService myservice = binder.getService();
myservice.setCallback(new MyService.Callback() {
@Override
public void onDateChanged(String str) {//非UI线程无法直接更新UI,需要通过handler机制
Message msg = new Message();
msg.arg1 = 1;
Bundle bundle = new Bundle();
bundle.putString("data", str);
msg.setData(bundle);
handler.sendMessage(msg);
}
});
}

通过这种方式就可以实现Service和Activity的通信工作,不难看出,Binder在其中起着非常重要的角色。

Android中进程间通信,从JAVA到C++基本上都是用Binder来实现的,上层使用的AIDL下一篇介绍一下,

这个系列只关注基础内容,希望可以坚持下来。

<Android 基础(一)> Service的更多相关文章

  1. 通过AngularJS实现前端与后台的数据对接(二)——服务(service,$http)篇

    什么是服务? 服务提供了一种能在应用的整个生命周期内保持数据的方法,它能够在控制器之间进行通信,并且能保证数据的一致性. 服务是一个单例对象,在每个应用中只会被实例化一次(被$injector实例化) ...

  2. Azure Service Fabric 开发环境搭建

    微服务体系结构是一种将服务器应用程序构建为一组小型服务的方法,每个服务都按自己的进程运行,并通过 HTTP 和 WebSocket 等协议相互通信.每个微服务都在特定的界定上下文(每服务)中实现特定的 ...

  3. 无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器端口相同。如果服务器位于远程计算机上,请检查。。。

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 无法向会话状态服务器发出会话状态请求.请确保 ASP.NET State Ser ...

  4. C#创建、安装、卸载、调试Windows Service(Windows 服务)的简单教程

    前言:Microsoft Windows 服务能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序.这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面.这 ...

  5. java中Action层、Service层和Dao层的功能区分

    Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DAO只 ...

  6. org.jboss.deployment.DeploymentException: Trying to install an already registered mbean: jboss.jca:service=LocalTxCM,name=egmasDS

    17:34:37,235 INFO [Http11Protocol] Starting Coyote HTTP/1.1 on http-0.0.0.0-8080 17:34:37,281 INFO [ ...

  7. Android—Service与Activity的交互

    service-Android的四大组件之一.人称"后台服务"指其本身的运行并不依赖于用户可视的UI界面 实际开发中我们经常需要service和activity之间可以相互传递数据 ...

  8. angularjs 1 开发简单案例(包含common.js,service.js,controller.js,page)

    common.js var app = angular.module('app', ['ngFileUpload']) .factory('SV_Common', function ($http) { ...

  9. IIS启动失败,启动Windows Process Activation Service时,出现错误13:数据无效 ;HTTP 错误 401.2 - Unauthorized 由于身份验证头无效,您无权查看此页

    因为修改过管理员账号的密码后重启服务器导致IIS无法启动,出现已下异常 1.解决:"启动Windows Process Activation Service时,出现错误13:数据无效&quo ...

  10. 如何利用mono把.net windows service程序迁移到linux上

    How to migrate a .NET Windows Service application to Linux using mono? 写在最前:之所以用要把windows程序迁移到Linux上 ...

随机推荐

  1. Springboot ResponseEntity IE无法正常下载文件

    项目在google浏览器下都很nice了,但当测试到IE的时候开始出现各种问题. 项目是前端js通过URL传参fileName到后台解析返回ResponseEntity 前端代码如下: window. ...

  2. AngularJs(Part 11)--自定义Directive

    先对自定义Directive有一个大体的映像 myModule.directive('myDirective',function(injectables){ var directiveDefiniti ...

  3. HTML中的ID不能以数字开头

    最近在学习网页制作,发现ID在w3c规范里是不能以一个数字开头的,chrome浏览器是可以,firefox就不能使用数字开头了,其它浏览器未测试. 记录一下! W3C规范链接:http://www.w ...

  4. Window 7 安装Docker toolbox , 启动terminal时遇到的小问题

    参考:http://blog.csdn.net/tina_ttl/article/details/51372604 参考前面网页成功安装后打开terminal,出现下面问题: Looks like s ...

  5. Oracle中 row_number() over()分析函数(转)

    https://www.cnblogs.com/moon-jiajun/p/3530035.html

  6. [Django笔记] uwsgi + nginx 配置

    django 和 nginx 通过 uwsgi 来处理请求,类似于 nginx + php-fpm + php 安装nginx 略 安装配置uwsgi pip install uwsgi 回想php- ...

  7. HDFS(Hadoop Distributed File System )hadoop分布式文件系统。

    HDFS(Hadoop Distributed File System )hadoop分布式文件系统.HDFS有如下特点:保存多个副本,且提供容错机制,副本丢失或宕机自动恢复.默认存3份.运行在廉价的 ...

  8. Hibernate的优化方案

    使用参数绑定 使用绑定参数的原因是让数据库一次解析SQL,对后续的重复请求可以使用生成好的执行计划,这样做节省CPU时间和内存. 避免SQL注入. 尽量少使用NOT 如果where子句中包含not关键 ...

  9. HDU2050 折线分割平面

    题目:acm.hdu.edu.cn/showproblem.php?pid=2050 递推: 从直线入手,第n条直线,最多和平面上的直线有n-1个交点,多出(n-1)+1个部分 序号 1 2 3 .. ...

  10. 位运算实现四则运算(C++实现)

    前言 Leetcode中有一道这样的题:给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符.返回被除数 dividend 除以除数 di ...