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 ...
随机推荐
- jquery请求解析xml
我们使用jque.ajax来做这个实验.其核心实现原理就是将请求回来的xml数据用$()选择器封装,然后进行傻瓜式操作. 代码如下: 需要注意的是请求数据格式要声明成:xml.不然不生效. $.aja ...
- nodejs安装sharp出错的问题
PS D:\report\source\lpd-planning-allocation> yarn yarn install v1.3.2 [/] Resolving packages... [ ...
- CodeForces 767B The Queue
模拟. 情况有点多,需要仔细.另外感觉题目的$tf$有点不太对......而且数据水了. $0$ $5$ $2$ $2$ $0$ $5$ 这组数据按照题意的话答案可以是$2$和$4$,但是好多错的答案 ...
- python3下安装aiohttp遇到过的那些坑
python3下安装aiohttp遇到过的那些坑 最近需要用到aiohttp这个库,在安装过程中遇到很多坑.google.baidu后,依然没有找到合适的解决方案. 后来通过去python官方的PyP ...
- [BZOJ3131] [Sdoi2013]淘金
[BZOJ3131] [Sdoi2013]淘金 Description 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐 ...
- 【Floyd】噪音恐惧症
[UVA10048]噪音恐惧症 题面略 试题分析:直接Floyd一下维护u到v的路径最大值最小就可以了,1A 代码: #include<iostream> #include<cstr ...
- [AGC026B]rng_10s
题意:一个商店,第一天早上有$A$罐苹果汁,一个人每天上午都会来买$B$罐,每天晚上如果剩余罐数$\leq C$那么会增加$D$罐,问能否无限买 收集一个套路...? 首先如果$B\gt A$或者$B ...
- 【最大流Dinic模板】HDU1532&POJ1273-Drainage Ditches(16/3/6更正)
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #inc ...
- Educational Codeforces Round 8 E. Zbazi in Zeydabad 树状数组
E. Zbazi in Zeydabad 题目连接: http://www.codeforces.com/contest/628/problem/D Description A tourist wan ...
- 如何获取php错误
今天把项目放在测试服务器,但是出现一个问题,用的TP5框架,我把入口文件放在了根目录,访问的时候报错了,框架引导文件引入不了,也不报错,就是说访问不了. 所以就用了一段代码把错误获取出来了,代码如下: ...