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 ...
随机推荐
- git学习资源合集
git官网 Pro git 电子书,这里还有中文版,这也是官方推荐的. 再加一个廖雪峰的简明git教程.
- 如何简单的测试kubernetes的dns add-ons是否工作正常?
1,新建一个yaml文件. apiVersion: v1 kind: Pod metadata: name: busybox namespace: default spec: containers: ...
- 封装CSS动画
写在前面:感谢腾讯课堂与妙味课堂的移动端公开课 对于需要设置动画的元素需要提前设置css()样式,这样数据才会被记录起来. function css(ele, attr, val) { if (/ro ...
- 在CentOS7.5的虚拟环境下新建你的django项目
1.首先安装pyenv和virtualenvs,之前的博客有说安装过程 2.创建Django专用的虚拟环境[root@localhost ~]# mkdir Django_env[root@local ...
- 创建 OpenStack云主机 (十五)
创建过程 创建虚拟网络 创建m1.nano规格的主机(相等于定义虚拟机的硬件配置) 生成一个密钥对(openstack的原理是不使用密码连接,而是使用密钥对进行连接) 增加安全组规则(用iptable ...
- C语言数据类型64位和32机器的区别
C语言编程需要注意的64位和32机器的区别 .数据类型特别是int相关的类型在不同位数机器的平台下长度不同.C99标准并不规定具体数据类型的长度大小,只规定级别.作下比较: 32位平台 char:1字 ...
- 链式前向星实现的堆优化dij求最短路模板
#include<cstdio> #include<string> #include<cstdlib> #include<cmath> #include ...
- go chapter 2 - read file(yaml)
func main() { data, err := ioutil.ReadFile("D:/test/widua.go") if err != nil { fmt.Println ...
- Python开发基础-Day14正则表达式和re模块
正则表达式 就其本质而言,正则表达式(或 re)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现.正则表达式模式被编译成一系列的字节码,然后由用 ...
- Codeforces 551 D. GukiZ and Binary Operations
\(>Codeforces \space 551 D. GukiZ and Binary Operations<\) 题目大意 :给出 \(n, \ k\) 求有多少个长度为 \(n\) ...