Android 组件之Service解析
原创文章,转载请注明 http://blog.csdn.net/leejizhou/article/details/50866875 李济洲的博客
Service是Android四大组件之中的一个。Service主要作用于后台,能够进行一些后台的操作,它没实用户界面。它跟Activity比較类似,某种意义上能够理解为“Service是没实用户界面的Activity“,那么我们什么时候须要使用Service呢?比如:音乐App正在播放音乐我们想切换到阅读App又不想让音乐停止就会用到Service,音乐App正在下载音乐我们切换到桌面又不想让下载停止就会使用到Service。
编写Activity须要两步:1:编写Activity的子类 2:在AndroidManifest.xml中配置此Activity,相同编写Service也须要两步:
1:定义一个继承自Service的子类
2:在AndroidManifest.xml中配置此Service
startService
我们先编写一个简单的StartService演示样例程序来演示怎样实现Android后台操作
先定义一个Service的子类,然后复写一些生命周期函数
/**
* Blog:http://blog.csdn.net/leejizhou
* 李济洲的博客
*/
public class MyService extends Service {
//Service中唯一的抽象方法。必须在子类中实现,用来和Activity通信。先返回NULL
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
//复写Service的一些生命周期函数
//onCreate会在Service第一次创建的时候调用
@Override
public void onCreate() {
super.onCreate();
Log.d("MyService","----onCreate executed----");
}
//onStartCommand会在Service每次启动的时候调用
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyService","----onStartCommand----");
return super.onStartCommand(intent, flags, startId);
}
//onDestroy会在Service销毁时候调用
@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyService", "----onDestroy----");
}
}
以下是Service的生命周期,为什么有两种呢?由于启动Servcie有两种方式第一个是startService()主要用于启动一个Service运行后台任务不进行通信,还有一个是bindService()是启动一个跟组件绑定的Service能够进行通信,先介绍的是startService()。
然后在AndroidManifest.xml中进行配置此Service。千万不要忘记。
<service android:name=".MyService"></service>
定义好Service后,接下来就是启动和停止这个服务了。启动和停止主要靠Intent来实现,这里我定义了两个Button用来启动和停止。部分代码略(文章结尾会提供源代码),主要看下启动和停止Service的实现代码。
//开启Service
findViewById(R.id.StartService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(MainActivity.this,MyService.class);
startService(intent);
}
});
//停止Service
findViewById(R.id.StopService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(MainActivity.this,MyService.class);
stopService(intent);
}
});
点击开启Service能够看到OnCreate和OnStartCommand被运行了,一个简单的后台Service就被启动了
然后点击停止。能够看到OnDestroy被运行了
这里可能你会问了。启动Service,OnCreate和OnStartCommand都被运行了,他俩有什么差别呢?onCreate会在Service第一次创建的时候调用,假设一个Service没有Stop再次启动这个Service的话是不会再调用onCreate方法了,可是每次OnStartCommand都会被调用。所以后台须要运行的代码逻辑我们一般须要放到OnStartCommand方法里面。
Ok 在Activity里面启动一个简单的Service后台服务就完毕了,可是你要知道的是通过startService()启动这个服务后就和Activity就没有关系了,即使你这个Activity被销毁这个Service依旧会在后台运行。切记通过startService()启动服务任务结束后在Activity中调用 stopService()结束掉这个Service。或者在Servcie子类中调用stopSelf()来结束自己。
上面介绍了startService启动服务,它能够很简单的启动后台Service进行一些逻辑操作,可是无法进行控制和通信,以下介绍下BindService能够解决问题。
bindService
以下实现一个后台Service进行数值的递增运算。Activity能够实时查看Service此时的数值的小演示样例来了解bindService的使用。
定义Service。这里我们要实现onBind的方法。在这里onStartCommand无需复写,由于通过bindService启动服务是不回调此方法的。Service的onCreate里面进行的了一个循环的数值运算。
/**
* Blog:http://blog.csdn.net/leejizhou
* 李济洲的博客
*/
public class MyService extends Service {
//当前数值
private int num=0;
//是否停止循环
private boolean isgo=true;
//BindService 须要实现onBind方法 自己定义一个Binder对象返回
private MyBinder binder=new MyBinder();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
public class MyBinder extends Binder{
//建立一个方法用于返回当前数值
public int getNum(){
return num;
}
}
//Service创建时候回调此方法 这里定义一个循环 不断更改num的值
@Override
public void onCreate() {
super.onCreate();
//进行循环操作,每秒数值加1
new Thread(new Runnable() {
@Override
public void run() {
while(isgo){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
num++;
Log.i("MyService",num+"");
}
}
}).start();
}
//这里不须要复写此方法。由于bindService启动服务不会调用此方法
// @Override
// public int onStartCommand(Intent intent, int flags, int startId) {
// return super.onStartCommand(intent, flags, startId);
// }
//Service断开时回调此方法
@Override
public boolean onUnbind(Intent intent) {
Log.i("MyService","----onUnbind----");
return super.onUnbind(intent);
}
//Service销毁是回调此方法
@Override
public void onDestroy() {
super.onDestroy();
isgo=false;
Log.i("MyService","----onDestroy----");
}
}
然后再AndroidManifest.xml中配置服务,一定一定一定不要忘记。
<service android:name=".MyService"></service>
之后在Activity里面通过bindService启动服务,Activity里面三个button用来启动 停止 和获取数值
/**
* Blog:http://blog.csdn.net/leejizhou
* 李济洲的博客
*/
public class MainActivity extends AppCompatActivity {
//获取Service中的Binder对象
MyService.MyBinder binder;
//定义一个ServiceConnection对象
private ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//Activity与Service连接成功时候回调此方法
binder=(MyService.MyBinder)service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
//Activity与Service断开连接时回调此方法,Activity主动调用unBindService将不掉用此方法。仅仅在异常终止时刻调用
Log.i("MyService","----onServiceDisconnected-----");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//启动Service
findViewById(R.id.bindService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent bindIntent=new Intent(MainActivity.this, MyService.class);
//这里第一个參数传入intent 第二个參数传入ServiceConnection对象
//第三个參数指Activity和Service绑定时是否创建服务。这里直接传BIND_AUTO_CREATE就好了。之后Service的onCreate会得到运行
bindService(bindIntent,connection, Service.BIND_AUTO_CREATE);
}
});
//停止Service
findViewById(R.id.UnBindService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//解除绑定Service
unbindService(connection);
}
});
//获取Service中此刻的数值
findViewById(R.id.getnum).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"Service的数值"+binder.getNum()+"",3000).show();
}
});
}
}
bindService运行生命周期
注意到Activity中ServiceConnection对象中的OnServiceConnected方法中有一个IBinder对象,该对象就可以实现Activity与Service之间的通信,使用bindService方式启动Service的时候,Service子类必须实现onBind方法,onBind方法返回的IBinder对象将会传递到onServiceConnected(ComponentName name, IBinder service)其中来实现通信交互。
这样Activity和Service通信的小演示样例就完毕了,值得注意的是通过onBind方法启动Service,Service和Activity是绑定状态的。那么假设Activity被销毁Service也会跟着一起销毁这点要注意,要区分startService和bindService的差别。
那么你可能会问假设我想让Service能够和Activity通信同一时候又能够不随Activity销毁该怎样做呢?仅仅须要 startService和bindService一起调用就能够了。假设同一时候调用了start和bind,那么调用unbindService将不会停止Service,而必须调用 stopService 或 Service的 stopSelf 来停止服务。
在使用Service中有一个误区会有人以为在Service中的onCreate中能够进行耗时操作。这是不正确的,Service依旧是运行在主线程中的,假设直接进行耗时操作很easy造成ANR,所以即使在Service中耗时操作依旧要放到子线程其中。
最后总结下什么情况下使用startService或bindService呢。假设你仅仅想启动一个后台服务去运行一个某项长期任务的话使用startService就能够了。假设你想要与正在运行的后台Service取得联系的话能够使用bindService,假设想要Service长期运行不随Activity销毁而且能够进行通信那么就调用了startService后再调用bindService。Service的总结先告一段落。有什么问题能够在下方留言,感谢。
Android 组件之Service解析的更多相关文章
- Android组件之Service浅谈
Service是Android中的四大组件之一,和windows中的服务是类似,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序Service,手机中有的程序的 ...
- Android组件系列----Android Service组件深入解析
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- Android四大组件之一 -- Service详解
相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了.Service作为Android四大组件之一,在每一个应用程序 ...
- 【Android开发精要笔记】Android组件模型解析
Android组件模型解析 Android中的Mashup 将应用切分成不同类别的组件,通过统一的定位模型和接口标准将他们整合在一起,来共同完成某项任务.在Android的Mashup模式下,每个组件 ...
- Android四大组件之Service
Android四大组件之Service Android支持服务的概念,服务是在后台运行的组件,没有用户界面,Android服务可用有与活动独立的生命周期.Android支持两种类型的服务: 本地服务: ...
- Java乔晓松-android的四大组件之一Service(服务的绑定)
android的四大组件之一Service(服务的绑定) 怎么绑定服务,又怎么解除服务,代码如下: MainActivity.java源码: package com.example.lesson14_ ...
- Android四大组件之一Service介绍-android学习之旅(十二)
基本概念: service是android四大组件之一,运行在后台执行耗时操作,并不提供用户界面.其他组件如acticity可以通过startService启动该组件,也可以通过bindService ...
- Android Service解析
Android Service是一个可以在后台执行长时间运行操作而不提供用户界面的应用组件,它分为两种工作状态,一种是启动状态,主要用于执行后台计算:另一种是绑定状态,主要用于其他组件和Service ...
- Android基础(五) Service全解析----看不见的Activity
一.服务的介绍: 作为Android四大组件之中的一个,Service(服务)也常常运用于我们的日常使用中,它与Activity的差别在于:Service一直在后台执行.没实用户界面.所以绝不会到前台 ...
随机推荐
- 求1+2+...+n 【微软面试100题 第十二题】
题目要求: 要求不能使用乘除法,for/while/if/else/switch/case等关键字以及条件判断语句(A?B:C). 参考资料:剑指offer第46题 题目分析: 方法1:利用类的静态成 ...
- python-网络编程-01
我们常说的计算机网络通信,值得是两台,或者多台计算机间,进行数据传输. 从计算机网络发展至今,人们使用了很多协议,但是最常用的还是tcp/ip协议,实际上这是一组协议. 当然使用python做网络编程 ...
- 【转】hibernate延迟加载和抓取策略
一.延迟加载 1.简单查询get,load 针对对象本身延迟或即时 当使用load方法来得到一个对象时,此时hibernate会使用延迟加载的机制来加载这个对象,即:当我们使用session.load ...
- shiro实现app和web统一登录
(转自:http://www.cnblogs.com/sunshine-2015/p/5515429.html) 先说下背景,项目包含一个管理系统(web)和门户网站(web),还有一个手机APP ...
- webstorm自带debugger服务器
打开webstorm->settings->Build,Execution,Deployment->Debugger->把端口Port改成8089或者其他80端口,按确定就可以 ...
- UVa——400Unix ls(字典序文本处理输出iomanip)
Unix ls Time Limit: 3000MS ...
- 刷题总结——pole(uva 1638 dp)
题目: 题解: 这道题很妙的一点是很好地利用了最矮的杆子除了放两侧以外对观察数是没有影响的性质·· 考虑n-1个杆子与n个杆子··我们可以把n个杆子的排列看成n-1个杆子的长度加1按原来的排列顺序·· ...
- UVa1362 Exploring Pyramids
区间dp,枚举走完第一个子树之后回到根节点的位置. /*by SilverN*/ #include<algorithm> #include<iostream> #include ...
- WebRTC VoiceEngine综合应用示例(一)——基本结构分析(转)
把自己这两天学习VoiceEngine的成果分享出来,供大家参考,有什么问题也欢迎大家指出,一起学习一起进步. 本文将对VoiceEngine的基本结构做一个分析,分析的方法是自底向上的:看一个音频编 ...
- 浅谈MVP设计模式
最近公司在做一个医疗项目,使用WinForm界面作为客户端交互界面.在整个客户端解决方案中.使用了MVP模式实现.由于之前没有接触过该设计模式,所以在项目完成到某个阶段时,将使用MVP的体会写在博客里 ...