介绍

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. Vmware克隆Centos 不能上网的解决方案

    问题:用Vmware克隆Centos 6.4后,发现系统内只有eth1,而且/etc/sysconfig/network-scripts/下只有,ifcfg-eth0文件,虽然可以上网,但无法设置静态 ...

  2. HDU 5973 Game of Taking Stones (威佐夫博弈+高精度)

    题意:给定两堆石子,每个人可以从任意一堆拿任意个,也可以从两堆中拿相同的数量,问谁赢. 析:直接运用威佐夫博弈,floor(abs(a, b) * (sqrt(5)+1)/2) == min(a, b ...

  3. docker私有仓库的搭建

    Docker搭建本地私有仓库的详细步骤 Dockers不仅提供了一个中央仓库,同时也允许我们使用registry搭建本地私有仓库.使用私有仓库有许多优点:一.节省网络带宽,针对于每个镜像,不用每个人都 ...

  4. Docker 容器的数据卷

    数据卷的特点: 1. 数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,这些数据会拷贝到新初始化的数据卷中 2. 数据卷可以在容器之间共享和重用 3. 可以对数据卷里的内容直接进行修改 ...

  5. 谢特——后缀数组+tire 树

    题目 [题目描述] 由于你成功地在 $ \text{1 s} $ 内算出了上一题的答案,英雄们很高兴并邀请你加入了他们的游戏.然而进入游戏之后你才发现,英雄们打的游戏和你想象的并不一样…… 英雄们打的 ...

  6. bzoj4200: [Noi2015]小园丁与老司机(可行流+dp)

    传送门 这该死的码农题…… 题解在这儿->这里 //minamoto #include<iostream> #include<cstdio> #include<cs ...

  7. 解读人:谭亦凡,Macrophage phosphoproteome analysis reveals MINCLE-dependent and -independent mycobacterial cord factor signaling(巨噬细胞磷酸化蛋白组学分析揭示MINCLE依赖和非依赖的分支杆菌索状因子信号通路)(MCP换)

    发表时间:2019年4月 IF:5.232 一. 概述: 分支杆菌索状因子TDM(trehalose-6,6’-dimycolate)能够与巨噬细胞C-型凝集素受体(CLR)MINCLE结合引起下游通 ...

  8. SnapKit swift实现高度自适应的新浪微博布局

    SnapKit swift版的自动布局框架,第一次使用感觉还不错. SnapKit是一个优秀的第三方自适应布局库,它可以让iOS.OS X应用更简单地实现自动布局(Auto Layout).GtiHu ...

  9. AT2657 Mole and Abandoned Mine

    传送门 好神的状压dp啊 首先考虑一个性质,删掉之后的图一定是个联通图 并且每个点最多只与保留下来的那条路径上的一个点有边相连 然后设状态:\(f[s][t]\)代表当前联通块的点的状态为\(s\)和 ...

  10. 省选九省联考T2 IIIDX(线段树)

    题目传送门:https://www.luogu.org/problemnew/show/P4364 期中考后记:期中考刚考完,感觉不咋滴,年排第3.我抗压力太差了..期末得把rank1抢回来. 本来感 ...