Android服务类Service具体解析
Service有什么作用?
很多人不明确service是用来干嘛的。事实上Service作为Android四大组件之中的一个,能够理解为一个执行在后台的Activity。它适用于处理一些不干扰用户的长时间的后台操作,比方你播放器播放音乐之后跳到其他页面,音乐须要继续播放。那么这个时候就能够将音乐的播放一直执行在后台服务中,须要启动播放的时候就通过Activity去启动服务。再通过服务去调用播放,须要停止的时候就停止服务。
有人可能会问,Thread也能够实现后台执行,为什么不用Thread而使用Service呢?
Service和Thread是全然不同的两个概念,thread是子线程,是与主线程没有交集的。而Service是执行在主线程上的。是与主线程有交集。当然你会说为什么服务执行在主线程中不会反而影响性能吗为何还要用它?事实上Service作为Android系统组件。是与Activity等立的,我们全然能够在当中定义子线程进行后台操作。假设须要大量的后台费时数据处理操作,最好的方式是在Service中开子线程。而不是直接开一个子线程,这样是为了提高子线程的优先级。而不会轻易被系统杀掉。
Thread是独立于主线程的,即使Activity结束了,假如你没有主动对它的子线程进行关闭。Thread仍有可能还在默默执行着,这个时候。你已经控制不到这些子线程了由于你已经把持有该Activity给结束掉了,这样对于程序非常不安全。
举个样例:假设你的应用是一个聊天的应用,须要创建一个Thread每隔一小段时间就去訪问server并实时显示有没有人发送了消息给你,那这个时候当你跳转到别的Activity比方个人设置等页面,而原来持有该Thread的Activity已经finfish,等你回去的时候已经控制不了你刚才在聊天Activity创建的那个子线程了,相同也就无法正常关闭这些子线程了。那么这个时候就须要service了,由于service是独立于Activity的,能够在当中创建子线程。即使Activity关闭了。也能够操作管理或者关闭这些子线程。并且不Service也不是和Activity一一相应,能够有多个Activity相应一个Service,这些Thread是无法做到的。
Service的用法:
原始方式创建服务:
定义一个类为MyService,继承自Service。并实现当中唯一的抽象方法:onbind(),其用处见下文:
public class MyService extends Service{
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
这样一个最原始的服务类就创建完毕,接下来我们要在Activity中去启动它(通过intent启动):
Intent intent = new Intent(MainActivity.this,MyService.class);
startService(intent);
这个时候我跑一下程序。会发现程序崩溃了。报错:android:content:ActivityNotFoundException:Unable to find exnlicit activity class。问题就在于Service也是Android四大组件之中的一个。必须要在AndroidMainfest.xml文件里注冊这个服务:
注冊完毕之后再执行一遍。便成功启动服务。
怎样停止服务:
Intent intent = new Intent(MainActivity.this,MyService.class);
stopService(intent);
绑定方式创建服务:
以上是通过startService方式启动服务,这样的情况下除非主动关闭,不然即使Activity关闭了,服务依然能够在后台一直执行
还有第二种能够通过与Activity绑定的服务,这样的情况下一旦Activity关闭了,服务也会相应关闭:
这时候就须要调用我们一開始说的onBind方法,binder在这个时候就相当于连接点:
在我们自己定义的MyService类中。加入一个IBinder对象,并创建一个MyBinder内部类,在里面定义一个方法能够获得当前服务,并且重写onBind以及onUnBind方法:
public class MyService extends Service{ private final IBinder binder = new MyBinder(); public class MyBinder extends Binder {
MyService getService() {
return MyService.this;
}
} @Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.d("MyService", "onBind...");
return binder;
} @Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
Log.d("MyService", "onUnBind...");
return super.onUnbind(intent);
}
}
这样的方式下启动服务须要通过调用onBind方法:
Intent intent = new Intent(MainActivity.this,MyService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);//这里即绑定并启动了服务
能够看到有3个參数,第一个即传入启动该MyService的intent,第二个传入的是一个ServiceConnection对象。第三个是调用系统的变量表示自己主动绑定,当中,connection的创建例如以下:
final ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
//onServiceDisconnected()方法在正常情况下是不被调用的,它的调用时机是当Service服务被异外销毁时 ,比如内存的资源不足时
} @Override
public void onServiceConnected(ComponentName arg0, IBinder binder) {
// TODO Auto-generated method stub
MyBinder mybinder = (MyBinder)binder;
MyService myservice = mybinder.getService(); //获得该服务
//在这里获取有关服务的各种信息包含状态等等
}
};
停止服务:通过调用onUnbind方法,传入刚才的connection。就会停止服务
上文我们用两种方式演示了怎样创建一个初始的Service,但会有疑问:怎样查看Service究竟执行了没有?
public boolean isServiceWork(Context mContext, String serviceName) {
boolean isWork = false;
ActivityManager myAM = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningServiceInfo> myList = myAM.getRunningServices(40);
if (myList.size() <= 0) {
return false;
}
for (int i = 0; i < myList.size(); i++) {
String mName = myList.get(i).service.getClassName().toString();
if (mName.equals(serviceName)) {
isWork = true;
break;
}
}
return isWork;
}
调用这种方法,并传入当前Activity的context,以及服务名:包名+服务的类名(比如:com.example.MyService)
假设结果返回true则表示正在执行,false表示已经关闭。
Service的生命周期:
原始方式的生命周期:
我们能够通过重写Service中的onCreate、onStartCommand、onDestroy方法并分别打印日志来进行查看:
public class MyService extends Service{ @Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
} @Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.d("MyService", "onCreate...");
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.d("MyService", "onStartCommand...");
return super.onStartCommand(intent, flags, startId);
} @Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.d("MyService", "onDestroy...");
} }
在布局文件里创建两个button:
代码调用:
startservice = (Button)this.findViewById(R.id.startservice);
stopservice = (Button)this.findViewById(R.id.stopservice);
startservice.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this,MyService.class);
startService(intent);
}
}); stopservice.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this,MyService.class);
stopService(intent);
}
});
执行程序,点击启动服务button,查看logcat打印:
再点击多几次启动服务button:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
点击关闭服务button:
能够看出,当我们第一次点击启动服务时。调用了服务的onCreate方法。当我们再点击多次启动时,仅仅调用服务的onStartCommand方法,点击关闭的时候,调用了服务的onDestroy方法。所以我们大概了解了服务的生命周期:
1.第一次启动服务时。调用onCreate
2.第二次启动服务时,不会再调用onCreate而是调用onStartCommand
3.关闭服务时。调用onDestroy销毁
流程图例如以下:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
绑定方式的生命周期:
代码上文已经讲述,这里不再描写叙述,同理在onBind和onUnBind方法中打印日志,可得到其执行流程例如以下:
onCreate --> onBind(仅仅一次,不可多次绑定) --> onUnbind --> onDestory
Android服务类Service具体解析的更多相关文章
- Android 服务类Service 的详细学习
http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建 目录(?)[+] 什么是服务 服务有 ...
- Android 服务类Service 的具体学习
上一篇说到了通知栏Notification,提起通知栏,不得让人想到Service以及BroadcastReceive,作为android的4大组建的2个重要成员,我们没少和它们打交道.它们能够在无形 ...
- Android服务之Service(其一)
android中服务是运行在后台的东西,级别与activity差不多.既然说service是运行在后台的服务,那么它就是不可见的,没有界面的东西.你可以启动一个服务Service来播放音乐,或者记录你 ...
- Android服务之Service
android中服务是运行在后台的东西,级别与activity差不多.既然说service是运行在后台的服务,那么它就是不可见的,没有界面的东西.你可以启动一个服务Service来播放音乐,或者记录你 ...
- Android基础(五) Service全解析----看不见的Activity
一.服务的介绍: 作为Android四大组件之中的一个,Service(服务)也常常运用于我们的日常使用中,它与Activity的差别在于:Service一直在后台执行.没实用户界面.所以绝不会到前台 ...
- Android 开发中Service完全解析
定义:服务,是Android四大组件之一,属于计算型组件 作用:提供 需在后台长期运行的服务 生命周期: 在Service的生命周期里,常用的有: (1) 4个手动调用的方法 手动调 ...
- Android Service完全解析,关于服务你所需知道的一切(下)
转载请注册出处:http://blog.csdn.net/guolin_blog/article/details/9797169 在上一篇文章中,我们学习了Android Service相关的许多重要 ...
- Android Service完全解析,关于服务你所需知道的一切(上)
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...
- 【转】Android Service完全解析,关于服务你所需知道的一切(下) ---- 不错
原文网址:http://blog.csdn.net/guolin_blog/article/details/9797169 转载请注册出处:http://blog.csdn.net/guolin_bl ...
随机推荐
- react 利用react-hammerjs插件实现滑动特效和点击特效
react-hammerjs是一款由hammer.js的JS插件来实现在react中实现手势滑动的事件插件, 它有各种各样的手势支持效果,这里我们就使用下它最简单的3种效果来实现我们要的动画 分别是点 ...
- HDU 2063.过山车-Hungary(匈牙利算法)
过山车 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- (8)C#字符串
一.字符串 为什么说string是一个不可变的字符序列. string a="me"; a="meeeee"; string b="me" ...
- 51nod 1133 不重叠的线段【贪心/区间覆盖】
1133 不重叠的线段 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 X轴上有N条线段,每条线段有1个起点S和终点E.最多能够选出多少条互不重叠的 ...
- Python的并发并行[1] -> 线程[3] -> 多线程的同步控制
多线程的控制方式 目录 唤醒单个线程等待 唤醒多个线程等待 条件函数等待 事件触发标志 函数延迟启动 设置线程障碍 1 唤醒单个线程等待 Condition类相当于一把高级的锁,可以进行一些复杂的线程 ...
- Python的网络编程[0] -> socket[1] -> socket 模块
socket 1. 常量 / Constants AF_* 和 SOCK_* 分别属于 AddressFamily 和 SocketType 1.1 AF_*类常量 socket.AF_UNIX: ...
- Python的网络编程[1] -> FTP 协议[1] -> 使用 pyftplib 建立 FTP 服务器
使用 pyftplib 建立 FTP 服务器 pyftplib 主要用于建立 FTP Server,与 ftplib 建立的 Client 进行通信. 快速导航 1. 模块信息 2. 建立 FTP 服 ...
- Xamarin XAML语言教程使用方法设置进度条进度
Xamarin XAML语言教程使用方法设置进度条进度 在ProgressBar中定义了一个ProgressTo方法,此方法也可以用来对进度条当前的进行进行设置,ProgressTo与Progress ...
- LINUX 下mysql导出数据、表结构
1.首先要确认mysqldump命令所在路径 例如,我的在:/usr/bin/ 下 [root@sf105113 bin]# which mysqldump /usr/bin/mysqldump 2. ...
- 咏南3层数据集控件--TYNDataSet
咏南3层数据集控件--TYNDataSet 和2层CS数据集的语法非常近似.有了这个控件,学习掌握3层开发变得如此地简单. 新增数据: procedure Tfunit.btnappendClick( ...