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 ...
随机推荐
- 利用SQL SERVER对比两张表的数据一致性
CREATE TABLE [dbo].[A]( [ID] [int] NULL, [NAME] [varchar](50) NULL, [SEX] [varchar](50) NUL ...
- vmware + ubuntu 64 安装 node.js v8.9.3
第一次使用虚拟机,第一次使用linux系统,第一次安装使用node.js 虚拟机安装不用多说,安装好之后下载ubuntu 64位版本文件 在vm中点击“创建新的虚拟机”,选择下载的ubuntu iso ...
- caffe-安装anaconda后重新编译caffe报错
ks@ks-go:~/caffe-master$ make -j16 CXX/LD -o .build_release/tools/convert_imageset.bin CXX/LD -o .bu ...
- python正则的中文处理(转)
匹配中文时,正则表达式规则和目标字串的编码格式必须相同 print sys.getdefaultencoding() text =u"#who#helloworld#a中文x#" ...
- 基于SAAJ的客户端
概述 SAAJ - SOAP with Attachments API for JAVA 结构图如下: 正文 1. 如何获取soap请求的关键参数 关键的参数有四个: xmlns - xml命名空间如 ...
- 在sublime Text 3上编写并运行java程序
参考 首先肯定是安装JDK配置环境变量,这个就不多说了. 第二步下载和安装sublime Text3. 第三步,创建一个批处理文件,命名为runJava.bat,放在JDK的bin下: @ECHO O ...
- SPOJ11469 Subset(折半枚举)
题意 给定一个集合,有多少个非空子集,能划分成和相等的两份.\(n\leq 20\) 题解 看到这个题,首先能想到的是\(3^n\)的暴力枚举,枚举当前元素是放入左边还是放入右边或者根本不放,但是显然 ...
- 北邮校赛 H. Black-white Tree (猜的)
H. Black-white Tree 2017- BUPT Collegiate Programming Contest - sync 时间限制 1000 ms 内存限制 65536 KB 题目描述 ...
- luogu P1016 旅行家的预算
题目描述 一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的).给定两个城市之间的距离D1.汽车油箱的容量C(以升为单位).每升汽油能行驶的距离D2.出发点每升汽油价格P和沿 ...
- SD 一轮集训 day4 弦形袋鼠
可以发现把每一个 a[i] * b[i] 加到矩阵里去,就相当于 把一个 1*m 的向量伸缩后变成 n个再加到矩阵里去,所以答案就是远=原矩阵中线性线性无关组的个数. (而且好像一个矩阵横着消元和竖着 ...