Android之旅七 Service简介
1、 Service是什么:它是一个应用程序组件、没有图形化界面、通常用来处理一些耗时比较长的操作(例如下载、播放MP3等等)、可以使用Service更新ContentProvider,发送Intent以及启动系统的通知等等。
2、 Service不是一个单独的进程,也不是一个线程
3、 要让系统知道我们的Service,我们仍然需要在AndroidMainifest.xml中进行注册。
<service android:name=".MyService"></service>
4、 启动一个Service使用startService(Intent);停止一个Service,stopService(Intent);
5、 我们还可以通过bindService()来启动一个Service,它与startService的区别是:通过startService()和stopService()启动关闭服务,适用于服务和访问者之间没有交互的情况,就是说Activity发送一个请求给Service,而Service是无法将信息或者它的状态传递给Activity的。如果服务和访问者之间需要方法调用或者传递参数或者知道其运行的情况,则需要使用bindService()和unbindService()方法启动关闭服务。
6、 Parcel就是一个存放读取数据的容器, Android系统中的binder进程间通信(IPC)就使用了Parcel类来进行客户端与服务端数据的交互,而且AIDL的数据也是通过Parcel来交互的。它可以存放任何类型的数据,得到Parcel对象通过Parcel.obtain()方法,通过writeXXX以及readXXX方法来存储和读取数据,数据都以二进制的形式被一个一个存放起来,当存入了很多数据,需要将其一个个取出来的时候,需要调用其setDatePosition方法将指针移动到最前面setDatePosition(0);
7、 通过在Service里面继承Binder的类中复写onTransact方法和在Activity里面通过Binder的transact方法可以实现Activity和Service之间的同步通信,相当与数据的发送和相应的一个过程,这在java web里面可以类似于客户端和服务器端的request、response数据交互。
8、 与Activity相似的是,Service中定义了系列生命周期方法,如下所示:
9、
代码一:通过startService和StopService启动、关闭Service
定义我们的Service类:
package com.service.test; import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException; public class MyService extends Service{ @Override
public IBinder onBind(Intent intent) {
System.out.println("service onBind");
IBinder binder=new FirstBinder();
//返回一个IBinder对象,将会调用客户端里面ServiceConnection中的onServiceConnected方法,并且将IBinder对象返回给客户端
//如果放回为null,将不会调用
return binder;
} class FirstBinder extends Binder{
public String getData(){
return "test data";
}
} /**
* 第一次调用Service(startService、bindService)的时候会调用onCreate方法
*/
@Override
public void onCreate() {
super.onCreate();
System.out.println("service onCreate");
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println(intent.getStringExtra("name"));
System.out.println(intent.getIntExtra("age", 0));
System.out.println("flags--->"+flags);
System.out.println("startId--->"+startId);
System.out.println("service onStartCommand");
return Service.START_NOT_STICKY;
} @Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
System.out.println("Service onStart");
} /**
* 当调用stopService和unbindService的时候会执行该方法
*/
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("service onDestroy");
} }
在Activity中调用startService和stopService方法:
//通过startService启动Service
class startServiceListener implements OnClickListener{
@Override
public void onClick(View v) {
Intent intent=new Intent();
intent.putExtra("name", "mary");
intent.putExtra("age", 32);
intent.setClass(MainActivity.this, MyService.class);
startService(intent);
}
} //通过stopService停止Service
class stopServiceListener implements OnClickListener{
@Override
public void onClick(View v) {
Intent intent=new Intent();
intent.setClass(MainActivity.this, MyService.class);
stopService(intent);
}
}
当我们执行startService时,我们自定义的Service中的onCreate、onStart、onStartCommand方法将会被执行,当我们执行stopService时,我们自定义的Service中的onDestory方法将会被执行。
在Activity中绑定Service,调用我们的bindService方法,其中,我们需要在Activity中创建一个连接对象ServiceConnection
//连接对象
private ServiceConnection conn=new ServiceConnection(){
//连接时调用
@Override
public void onServiceConnected(ComponentName name, IBinder FirstBinder) {
System.out.println("service bind successed!");
FirstBinder binder=(FirstBinder)FirstBinder;
System.out.println(binder.getData());
Toast.makeText(MainActivity.this, "绑定成功!", Toast.LENGTH_LONG).show();
} //断开连接时调用
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("service unbind");
}
};
绑定Service:
//通过bindService来绑定Service
class bindServiceListener implements OnClickListener{
@Override
public void onClick(View v) {
Intent intent=new Intent();
intent.setClass(MainActivity.this, MyService.class);
bindService(intent, conn, Service.BIND_AUTO_CREATE);
}
}
解除绑定Service:
class unbindServiceListener implements OnClickListener{
@Override
public void onClick(View v) {
Intent intent=new Intent();
intent.setClass(MainActivity.this, MyService.class);
unbindService(conn);
} }
当我们执行bindService方法的时候,我们自定义的Service中的onCreate、onBinder方法将会被执行,当我们执行unbindService方法的时候,我们自定义的Service中的onDestory方法将会被执行。
所以Service的生命周期大致为:
如果应用程序通过startService()方法来启动Service,Service的生命周期:
程序通过bindService()方法来启动Service,Service的生命周期:
通过bindService实现Activity和Service的数据交互 ,通过Binder里面的onTransact和transact方法
定义我们的Service:注意要在AndroidMainifest.xml文件中进行配置:
package com.harderxin.service; import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException; public class FirstService extends Service { @Override
public IBinder onBind(Intent intent) {
return new FirstBinder();
} class FirstBinder extends Binder{ @Override
protected boolean onTransact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
System.out.println("code---->"+code);
String str=data.readString();//接收Activity发送过来的请求
System.out.println(str);//处理请求
reply.writeString("from Service:reply");//Service将数据回送发给Activity
return super.onTransact(code, data, reply, flags);
}
} }
在Activity中绑定service和发送请求给Service:
package com.harderxin.service; import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button; /**
* 实现了Activity和Service进行数据交互的一个过程,通过Binder里面的onTransact和transact方法进行实现
* binder.transact(int code, Parcel data, Parcel reply,int flags);用户将data.writeXXX里面的数据发送给Service
* Service通过onTransact(int code, Parcel data, Parcel reply,int flags);接收里面的data.readXXX数据,进行一系列的逻辑处理后
* 通过reply.writeXXX将消息反馈给Activity,Activity通过reply.readXXX接收Service反馈过来的数据,这样就实现了客户端和服务端的通信
* 的一个过程,并且这个过程是同步的,就是说binder.transact(0, data, reply, 0)和onTransact是同步进行的,请求发送---接收--回复--收到
* 不会说哪个先执行完
* @author Administrator
*
*/
public class MainActivity extends Activity {
private Button bindService=null;
private Button sendReply=null;
private Binder binder=null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bindService=(Button)findViewById(R.id.bindService);
sendReply=(Button)findViewById(R.id.sendReply);
bindService.setOnClickListener(new bindServiceListener());
sendReply.setOnClickListener(new sendReplyListener());
} class bindServiceListener implements OnClickListener{
@Override
public void onClick(View v) {
Intent intent=new Intent();
intent.setClass(MainActivity.this,FirstService.class);
bindService(intent, conn, Service.BIND_AUTO_CREATE);
}
} class sendReplyListener implements OnClickListener{
@Override
public void onClick(View v) {
Parcel data=Parcel.obtain();//获得Parcel对象,一个存放读取数据的容器
Parcel reply=Parcel.obtain();//获得Parcel对象
data.writeString("from activity:data");//发送请求给Service
try {
binder.transact(0, data, reply, 0);
String str=reply.readString();//接收Service发送过来的数据
System.out.println(str);
} catch (RemoteException e) {
e.printStackTrace();
}
}
} private ServiceConnection conn=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MainActivity.this.binder=(Binder)service;//将从service返回过来的IBinder对象赋值给当前对象里面的binder
} @Override
public void onServiceDisconnected(ComponentName name) { }
};
}
Android之旅七 Service简介的更多相关文章
- Android菜鸟的成长笔记(16)——Service简介
Service是Android四大组件之一 1.Service与Activity的区别在:Service一直在后台运行,没有用户界面. 2.选择Activity与Service的标准:如果某个程序组件 ...
- 谈Android四大组件之Service篇
Service简介 Service是Android系统中的四大组件之一,它是一种长生命周期的,没有可视化界面,运行于后台的一种服务程序.Service必须在AndroidManifest.xml中声明 ...
- Android之旅:梦想、学习、坚持、自信、淡定
前段时间参加了2012年度IT博客大赛,进了前十强,写了一篇获奖感言,不过还没正式在CSDN发表出来.眼看2012年就要结束了,刚好借这个机会将2012年度IT博客大十强获奖感言发表出来,也算是对20 ...
- Android菜鸟的成长笔记(17)—— 再看Android中的Unbounded Service
原文:Android菜鸟的成长笔记(17)-- 再看Android中的Unbounded Service 前面已经写过关于startService(Unbounded Service)的一篇文章:&l ...
- 转载_2012年的Android之旅:梦想、学习、坚持、自信、淡定
原文地址:http://blog.csdn.net/luoshengyang/article/details/8452527 2012年的Android之旅:梦想.学习.坚持.自信.淡定.. ---- ...
- 《老罗的Android之旅》导读PPT
虽然好几个月没更新博客了,但是老罗一直有在准备可以分享的东西的.除了早前在微博分享Android4.2相关技术之外,这次还特意准备了13个PPT,总结之前所研究过的东西.内容从Android组件设计思 ...
- Service 简介 启动方式 生命周期 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Service简介 demos
extends:http://blog.csdn.net/ithomer/article/details/7364024 一. Service简介 Service是android 系统中的四大组件之一 ...
- 八、Android学习第七天——XML文件解析方法(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 八.Android学习第七天——XML文件解析方法 XML文件:exten ...
随机推荐
- AC日记——「SCOI2015」国旗计划 LiBreOJ 2007
#2007. 「SCOI2015」国旗计划 思路: 跪烂Claris 代码: #include <cstdio> #include <algorithm> #define ma ...
- CSS3主要的几个样式笔记
1.边框:border-color: 设置对象边框的颜色. 使用CSS3的border-radius属性,如果你设置了border的宽度是X px,那么你就可以在这个border上使用X ...
- Protocol Buffers 在前端项目中的使用
前言: 公司后端使用的是go语言,想尝试用pb和前端进行交互,于是便有了这一次尝试,共计花了一星期时间,网上能查到的文档几乎都看了一遍,但大多都是教在node环境下如何使用,普通的js环境下很多讲述的 ...
- Spring学习的切入点
spring是个顶级的框架,这话没毛病.很多人想把它征服,想去阅读它的源码,弄懂它的设计思想,从中学到精粹. 但是很多次打开后,看到庞大的体系结构,就懵逼了,不知从何入手. 我在这里总结下学习spri ...
- 用Pandas获取商品期货价格并可视化
用Pandas获取商品期货价格并可视化 摘 要 1.用pandas从excel中读取数据: 2.用pandas进行数据清洗.整理: 3.用bokeh进行简单的可视化. 1.数据读取 本文主要是将获 ...
- coreseek 段错误 (core dumped) 问题
coreseek建立索引出现上面问题经过测试发现有下面几个原因: 1. 分词配置文件不存在 uni.lib 2. uni.lib配置文件格式不正确
- Redux-react connect 源码自己重写
import Counter from '../components/Counter'; import { increment, decrement, incrementIfOdd, incremen ...
- Sd - JavaBase问题
1. Java有哪些基本数据类型 2. Java基本数据类型和引用类型的区别 3. Java的多态 4. Override和Overload的区别 5. Java内部类 6. 继承和组合的比较 7. ...
- [HDU5354]Bipartite Graph(CDQ分治+并查集)
经典动态二分图问题. 考虑solve(l,r)分治成l,mid和mid+1,r.先将区间[mid+1,r]中的点全部加入图中,若此时存在奇环则ans[l..mid]全部为0,否则递归到左边. 递归完左 ...
- BZOJ 1430 小猴打架(prufer编码)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1430 [题目大意] 一开始森林里面有N只互不相识的小猴子,它们经常打架, 但打架的双方 ...