Android服务(Service)研究
Service是android四大组件之一,没有用户界面,一直在后台运行。
为什么使用Service启动新线程执行耗时任务,而不直接在Activity中启动一个子线程处理?
1、Activity会被用户退出,Activity所在的进程就变成了空进程(没有任何活动组件的进程),系统需要内存可能会优先终止该进程;
2、如果宿主进程被终止,那么该进程内所有的子线程也会被终止,这样可能导致子线程无法执行完成;
3、其实两种方式都是可以处理耗时任务的,使用场景不同而已。
一、通过Start方式启动Service
这种方式启动的Sevice,访问者与service之间没有关联,即使访问者退出Service仍然执行
生命周期:onCreate()->onStartCommand()->onDestroy()
》定义一个继承Service的子类
public class NormalService extends Service {
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "启动成功", Toast.LENGTH_SHORT).show();
Log.d("NormalService", "启动成功");
//一般在这里启动新线程执行耗时的操作
return super.onStartCommand(intent, flags, startId);
}
}
》在AndroidManifest.xml文件中配置该Service
<service android:name="com.android.servicetest.service.NormalService" />
》在activity中使用
private void startNormal() {
nomalIntent = new Intent();
nomalIntent.setClass(this, NormalService.class);
startService(nomalIntent);
}
二、通过bind方式启动Service
这种方式启动的Sercice,访问者与Service绑定在一起,访问者退出,Service也就终止了
生命周期:onCreate()->onBind()->onUnbind()->onDestroy()
》定义一个继承Service的子类
public class BinderService extends Service {
private int count;
private MyBinder mBinder;
@Override
public IBinder onBind(Intent arg0) {
if (mBinder == null) {
mBinder = new MyBinder();
}
Toast.makeText(this, "绑定成功", Toast.LENGTH_SHORT).show();
Log.d("BinderService", "绑定成功");
return mBinder;
}
@Override
public void onCreate() {
super.onCreate();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
count++;
} catch (Exception e) {
}
}
}
}).start();
}
public class MyBinder extends Binder {
public int getCount() {
return count;
}
}
}
》在AndroidManifest.xml文件中配置该Service
<service android:name="com.android.servicetest.service.BinderService" />
》在activity中使用
private MyBinder mBinder;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName arg0) {
}
@Override
public void onServiceConnected(ComponentName arg0, IBinder binder) {
mBinder = (BinderService.MyBinder) binder;
}
};
private void bindService() {
bindIntent = new Intent();
bindIntent.setClass(this, BinderService.class);
bindService(bindIntent, conn, Service.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(conn);
}
Binder对象相当于Service组件的内部钩子,关联到绑定的Service组件;
当其他的程序组件绑定该Service时,Service会把Binder对象返回给其他程序组件,其他程序组件通过该Binder对象即可与Service组件进行实时通信。
三、IntentService,处理异步请求的服务
IntentService是Service的子类,它增加了额外的功能:
使用队列来管理请求Intent,每当客户端代码通过Intent请求启动IntentService时,IntentService会将该Intent加入队列中,然后开启一条新的worker线程处理队列中的Intent,因此不会阻塞主线程。
IntentService会按次序处理队列中的Intent,该线程保证同一时刻只处理一个Intent。
》IntentService的实现
public class IntentServiceTest extends IntentService{
public IntentServiceTest() {
super("IntentService");
}
@Override
protected void onHandleIntent(Intent arg0) {
Toast.makeText(this, "启动成功", Toast.LENGTH_SHORT).show();
Log.d("IntentServiceTest", "启动成功");
//该方法可以执行耗时的操作
long endTime = System.currentTimeMillis() + 20 * 1000;
while(System.currentTimeMillis() < endTime){
synchronized (this) {
try{
wait(endTime - System.currentTimeMillis());
}catch(Exception e){
}
}
}
}
}
》在AndroidManifest.xml文件中配置该Service
<service android:name="com.android.servicetest.service.IntentServiceTest" />
》在activity中使用
private void startIntentService(){
serviceIntent = new Intent();
serviceIntent.setClass(this, IntentServiceTest.class);
startService(serviceIntent);
}
四、跨进程调用Service(AIDL Service)
Android各应用程序都运行在自己的进程中,进程之间无法直接进行数据交换,为了事项这种跨进程通信,Android提供了AIDL Service。
》创建AIDL文件,定义接口的源代码必须以.aidl结尾
package com.android.servicetest.service;
interface IMusic{
String getName();
String getYear();
}
定义好AIDL接口之后,ADT工具会自动在gen/com/android/servicetest/service/目录生成一个IMusic接口;
在该接口里包含一个Stub内部类,该内部类除了实现IMusic接口还实现了IBinder接口,这个Stub类将会作为远程Service的回调类。
》定义一个Service实现类
public class MusicService extends Service{
private MusicBinder mBinder;
@Override
public IBinder onBind(Intent arg0) {
if(mBinder == null){
mBinder = new MusicBinder();
}
Toast.makeText(this, "绑定成功", Toast.LENGTH_SHORT).show();
Log.d("MusicService", "绑定成功");
return mBinder;
}
public class MusicBinder extends IMusic.Stub{
@Override
public String getName() throws RemoteException {
return "本草纲目";
}
@Override
public String getYear() throws RemoteException {
return "2006";
}
}
}
》在AndroidManifest.xml文件中配置该Service
<service android:name="com.android.servicetest.service.MusicService" />
》在activity中使用
private IMusic musicService;
private ServiceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName arg0) {
}
@Override
public void onServiceConnected(ComponentName arg0, IBinder binder) {
//获取远程Service的OnBind方法返回的对象的代理
musicService = IMusic.Stub.asInterface(binder);
}
};
private void bindAidlService(){
aidlIntent = new Intent();
aidlIntent.setClass(this, MusicService.class);
bindService(aidlIntent, connAidl, Service.BIND_AUTO_CREATE);
}
private void showContent() {
String content = "";
try {
content = musicService.getYear() + musicService.getName();
} catch (Exception e) {
}
Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(connAidl);
}
这种方式和绑定本地Service的差别很小,只是获取Service回调的方式有区别:
绑定本地Service时可以直接获取OnBind方法的返回值;绑定远程Service时获取的事OnBind方法返回的对象的代理。
Android服务(Service)研究的更多相关文章
- Android服务Service具体解释(作用,生命周期,AIDL)系列文章-为什么须要服务呢?
Android服务Service具体解释(作用,生命周期,AIDL) 近期沉迷于上班,没有时间写博客了.解衣入睡,未眠.随起床写一篇博客压压惊! ##我们android系统为什么须要服务Service ...
- Android服务Service总结
转自 http://blog.csdn.net/liuhe688/article/details/6874378 富貴必從勤苦得,男兒須讀五車書.唐.杜甫<柏學士茅屋> 作为程序员的我们, ...
- android服务Service(上)- IntentService
Android学习笔记(五一):服务Service(上)- IntentService 对于需要长期运行,例如播放音乐.长期和服务器的连接,即使已不是屏幕当前的activity仍需要运行的情况,采用服 ...
- Android服务——Service
服务 Service 是一个可以在后台执行长时间运行操作而不使用用户界面的应用组件.服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行. 此外,组件可以绑定到服务,以与之进行 ...
- Android服务Service
安卓Service服务 一 Service简介 Service是运行在后台的,没有界面的,用来处理耗时比较长的.Service不是一个单独的进程,也不是一个单独的线程. Service有两种类型 ...
- android 服务service开启和关闭
startService()方法开启一个服务. 服务只会开启一次,如果服务已经创建,并且没有销毁,多次调用startService方法只会执行onStartCommand方法和onStart方法. 服 ...
- Android中Service(服务)详解
http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...
- Android服务之Service(其一)
android中服务是运行在后台的东西,级别与activity差不多.既然说service是运行在后台的服务,那么它就是不可见的,没有界面的东西.你可以启动一个服务Service来播放音乐,或者记录你 ...
- Android 服务类Service 的详细学习
http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建 目录(?)[+] 什么是服务 服务有 ...
随机推荐
- JMS开发步骤和持久化/非持久化Topic消息
------------------------------------------------ 开发一个JMS的基本步骤如下: 1.创建一个JMS connection factory 2.通过co ...
- CSS百分比定义高度的冷知识
当我们给块级元素设置响应式高度的时候,例如给div设置height=50%,往往没能看到效果. 原因是百分比的大小是相对其父级元素宽高的大小,如最外层元素设置的百分比是对应屏幕而言的. 需要了解的是对 ...
- [BZOJ3173][Tjoi2013]最长上升子序列
[BZOJ3173][Tjoi2013]最长上升子序列 试题描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上 ...
- 欢迎加入threejs
Threejs is the coolest graphics rendering engine I have ever seen, so what is threejs, Now, we have ...
- dp 走格子问题
问题: 一个5x8的格子,想从左下角走到右上角,求最短路径,共有多少种走法. 思路: 因为是求最短路径,所以,只会往右往上走. 我们可以把棋盘的左下角看做二维坐标的原点(0,0),把棋盘的右上角看做二 ...
- gulp使用技巧-删除node_modules文件夹,解决目录层次太深删除报错的问题
问题描述: 在使用gulp当中,自动生成的node_modules文件夹,因为文件目录层级太深,无法系统删除,用360粉碎工具也报错 解决方法: 使用npm中的插件rimraf,专门用于删除的模块插件 ...
- (转: daifubing的博客 )Delphi二维码中文支持、分组、批量打印经验小结
一直也没接触到什么复杂的报表,都是一些简单的报表,在DelphI下使用QuickReport一般也就能满足需要了,由于公司现在需求的变化,对条码扫描提出了新的要求,主要是扫码要包含更多地内容,以前的一 ...
- MapKit/CoreLocation框架 总结
MapKit/CoreLocation框架 /*英译 core:核心 track:踪迹 current:当前 statellite:卫星 hybird:混合 region:范围 annotation ...
- 根据字体计算CGRect
UILabel *label = [[UILabel alloc]init]; label.numberOfLines = ;//多行显示 label.backgroundColor = [UICol ...
- 图像处理中的matlab使用
图像的矩阵表示 类和图像类型 虽然使用的是整数坐标, 但 MATLAB 中的像素值(亮度)并未限制为整数. 表 1-1 列出了 MATLAB 和图像处理工具箱为描述像素值而支持的各种类. 表中的前 8 ...