<Android 基础(一)> Service
介绍
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);
}
}
测试结果
启动服务,停止服务
绑定服务,解绑服务
启动服务,绑定服务,解绑服务
注意:这里最后Service是没有onDestory的启动服务,绑定服务,解绑服务,停止服务
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的更多相关文章
- 通过AngularJS实现前端与后台的数据对接(二)——服务(service,$http)篇
什么是服务? 服务提供了一种能在应用的整个生命周期内保持数据的方法,它能够在控制器之间进行通信,并且能保证数据的一致性. 服务是一个单例对象,在每个应用中只会被实例化一次(被$injector实例化) ...
- Azure Service Fabric 开发环境搭建
微服务体系结构是一种将服务器应用程序构建为一组小型服务的方法,每个服务都按自己的进程运行,并通过 HTTP 和 WebSocket 等协议相互通信.每个微服务都在特定的界定上下文(每服务)中实现特定的 ...
- 无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器端口相同。如果服务器位于远程计算机上,请检查。。。
异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 无法向会话状态服务器发出会话状态请求.请确保 ASP.NET State Ser ...
- C#创建、安装、卸载、调试Windows Service(Windows 服务)的简单教程
前言:Microsoft Windows 服务能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序.这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面.这 ...
- java中Action层、Service层和Dao层的功能区分
Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DAO只 ...
- 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 [ ...
- Android—Service与Activity的交互
service-Android的四大组件之一.人称"后台服务"指其本身的运行并不依赖于用户可视的UI界面 实际开发中我们经常需要service和activity之间可以相互传递数据 ...
- angularjs 1 开发简单案例(包含common.js,service.js,controller.js,page)
common.js var app = angular.module('app', ['ngFileUpload']) .factory('SV_Common', function ($http) { ...
- IIS启动失败,启动Windows Process Activation Service时,出现错误13:数据无效 ;HTTP 错误 401.2 - Unauthorized 由于身份验证头无效,您无权查看此页
因为修改过管理员账号的密码后重启服务器导致IIS无法启动,出现已下异常 1.解决:"启动Windows Process Activation Service时,出现错误13:数据无效&quo ...
- 如何利用mono把.net windows service程序迁移到linux上
How to migrate a .NET Windows Service application to Linux using mono? 写在最前:之所以用要把windows程序迁移到Linux上 ...
随机推荐
- hadoop作业调优参数整理及原理
hadoop作业调优参数整理及原理 10/22. 2013 1 Map side tuning参数 1.1 MapTask运行内部原理 当map task开始运算,并产生中间数据时,其产生的中间结果并 ...
- 6、git和github
参考:http://www.cnblogs.com/qianmojing/p/6484162.htmlhttp://www.jb51.net/article/70729.htmhttp://www.c ...
- Java中编写线程安全代码的原理(Java concurrent in practice的快速要点)
Java concurrent in practice是一本好书,不过太繁冗.本文主要简述第一部分的内容. 多线程 优势 与单线程相比,可以利用多核的能力; 可以方便的建模成一个线程处理一种任务; 与 ...
- Python中的try和except语句
Python中是通过缩进来解析代码块的,要特别注意tab和空格符,两者不可以混用,通常情况下用四个空格来代替tab键 下面通过一个简单的例子来说明 提示用户输入工作的时间和每小时的时薪,如果超过40个 ...
- 反射实现增删改查(DAO层)——查询数据
先贴出代码,后续补充自己的思路.配置文件.使用方式: /** * * 数据查询 * */ @Override public List<?> queryObject(List<Map& ...
- cf873F(xjb+二分)
题目链接:http://codeforces.com/problemset/problem/837/F 题意:给出一个大小为 n 的数组 a 和一个数 k,每次操作后的到一个 a' 数组,a'i 为 ...
- Mysql-15-mysql分布式应用
1.分布式应用的概念和优势 分布式数据库是指利用高速网络将物理上分散的多个数据存储单元连接起来组成一个逻辑上统一的数据库.分布式数据库的基本思想是将原来集中式数据库中的数据分散存储到多个通过网络连接的 ...
- linux日志守护进程 syslog
几乎所有的网络设备都可以通过syslog协议,将日志信息以UDP的形式传送给远端服务器,远端接收日志服务器必须通过syslogd监听UDP端口514,并根据 syslog.conf 配置文件张的配置处 ...
- React方法论
按照目前学习进度不定更新 react渲染的效率,看起来是全体的渲染,其实react在虚拟dom上的处理简直完美.它会过滤掉那些原来就有的东西,不去全体地重复渲染一遍. 即将进入实战,React至今的个 ...
- Leetcode初级算法(链表篇)
删除链表的倒数第N个节点 感觉自己对于链表的知识还是了解的不够深入,所以没有想到用双指针进行操作.我的想法是这样的,首先计算整个链表的长度,然后遍历到长度减去n的节点处,执行删除操作. 自己的代码: ...