Android基础知识——Service

Android下的服务是在后台运行 也是没有界面 可以理解成是没有界面的Activity,Android系统会为每个 应用程序创建一个进程和线程(主线程),而开启一个服务就会创建一个进程,可以在后台看到。

我们来分析一下进程:

    进程按优先级分5中:

          1.Foreground process 前台进程,正在和用户交互 相当于Activity执行了onResume方法这个进程最不容易被系统杀死。       

           2.Visible Process  可视化进程,用户可以看得见,但用户不能进行交互,相当于Activity执行了onPause()方法。

           3.Service Process  服务进程 , 当进程里面通过startService开启一个服务,这时候就属于服务进程。

           4. Background Process  后台进程, 相当于Activity执行了onStop()方法。

           5. Empty  Process  空进程    空进程不会维持任何运行的组件,空进程最容易被杀死,有时候它没有被立刻杀死的目的是为下一次打开应用程序时提供打开的速度。

          在系统运行内存不足的情况下,会检查正在正在运行的进程,杀死优先级低的进程来腾出内存。


我们开启服务有两种方式: StartService()和BindService().

(a)started(启动):当应用程序组件(如activity)调用startService()方法启动服务时,服务处于started状态。

        starService 开启一个服务,会执行onCreate()方法,和onStart()方法,如果服务已经开启,只会执行onStart()方法。

    服务开启后,就会在后台长期运行,可以在设置界面找到,我们可以在设置界面手动关闭它,服务就会停止运行。

        startService开启服务也叫做非绑定模式开启服务 ,生命周期  第一次执行的方法有 onCreate().onstartCommand(),到service关闭的时候执行onDestroy()方法。

(b)bound(绑定):当应用程序组件调用bindService()方法绑定到服务时,服务处于bound状态。

bindService开启服务也叫做绑定模式开启服务,生命周期 第一次执行的方法有 onCreate(), onBind()方法,销毁的时候执行onUnBind(),onDestroy()方法, bindService开启服务有个特点,它在设置界面时找不到的,所以我们无法手动在设置界面销毁它,不过它的生命周期依附于Activity,当Activity销毁的时候,这个服务也就跟着销毁。

    上面两种生命周期实在相对单纯的模式下的情形,我们在开发的过程中还必须注意Service实例只会有一个,也就是说如果当前要启动的Service已经存在了那么就不会再次创建该Service当然也不会调用onCreate()方法;

   一个Service可以被多个客户进行绑定,只有所有绑定对象都执行了unBind()方法后该Service才会销毁,不过如果有一个用户执行了onStart()方法,那么这个时候如果其他所有的bind客户都执行了unBind(),该Service也不会销毁. 很多应用都是用startService和bindService混合开启服务,比如音乐播放器,第三方支付等


Service生命周期

 startService()与bindService()区别:

(a)started service(启动服务)是由其他组件调用startService()方法启动的,这导致服务的onStartCommand()方法被调用。当服务是started状态时,其生命周期与启动它的组件无关,并且可以在后台无限期运行,即使启动服务的组件已经被销毁。因此,服务需要在完成任务后调用stopSelf()方法停止,或者由其他组件调用stopService()方法停止。

(b)使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。

 开发人员需要在应用程序配置文件中声明全部的service,使用标签。

 Service通常位于后台运行,它一般不需要与用户交互,因此Service组件没有图形用户界面。Service组件需要继承Service基类。Service组件通常用于为其他组件提供后台服务或监控其他组件的运行状态。

 这时我们可能会有一个疑问:既然有StartService开启服务,为什么还要用bindService开启服务?

目的就是为了使用bindserivce调用服务里面的方法

这时就出现了解决进程间的通信问题:IPC,

而使用IPC就需要使用 aidl.

aidl :Android inteface defation language Android接口定义语言

使用aidl语言的步骤 

   [1] 有一个服务 服务里面有一个方法  这个方法在另外一个应用里面调用  

    [2]在服务的内部定义一个中间人对象(IBinder的实例)

[3]在onbind方法里面把我们定义的中间人对象返回

[4]把你想暴露的方法都定义在接口里

[5]把定义的接口Iservice.java 文件变成aidl文件   注意aidl语言不认识public

   [6]系统会自动生产一个Iservice.java文件  生产一个类 stub 系统会报错. 把我们定义的中间人对象直接继承Stub

   [7]想保证2个应用程序使用的是同一个aidl文件 谷歌要求aidl文件所生成的包名要相同 

   [8]获取中间人对象方式不一样  是通过stub类中的一个静态方法获取我们定义中间人对象

[9]通过获取到的中间人对象,调用服务里面的方法,实现IPC通信

两种开启服务的小demo:

public class MainActivity extends Activity {  

private MyConn conn;  

@Override  

protected void onCreate(Bundle savedInstanceState) {  

super.onCreate(savedInstanceState);  

        setContentView(R.layout.activity_main);  

    }  

// 点击按钮开启服务  

public void click1(View v) {  

Intent intent =new Intent(this, FirstService.class);  

        startService(intent);  

    }  

// 点击按钮关闭服务  

public void click2(View v) {  

Intent intent =new Intent(this, FirstService.class);  

        stopService(intent);  

    }  

//点击按钮 通过bindservice 去连接服务  

public void click3(View v) {  

Intent intent =new Intent(this, FirstService.class);  

conn =new MyConn();  

        bindService(intent, conn, BIND_AUTO_CREATE);  

    }  

//点击按钮 停止服务   

public void click4(View v) {  

Intent intent =new Intent(this, FirstService.class);  

        stopService(intent);  

    }  

//当Activity销毁的时候   

@Override  

protected void onDestroy() {  

//取消绑定服务   

        unbindService(conn);  

super.onDestroy();  

    }  

//监听服务的状态   

private class MyConn implements ServiceConnection{  

//当服务连接成功的时候调用  

@Override  

public void onServiceConnected(ComponentName name, IBinder service) {  

        }  

//失去连接的时候调用  

@Override  

public void onServiceDisconnected(ComponentName name) {  

        }  

    }  

}

public class FirstService extends Service { 

 //当通过bindservice 连接成功的时候执行  

@Override  

public IBinder onBind(Intent intent) {  

System.out.println("onBind");  

return null;  

    }  

//当service第一次创建的时候调用  

@Override  

public void onCreate() {  

System.out.println("onCreate");  

super.onCreate();  

    }  

@Override  

public int onStartCommand(Intent intent, int flags, int startId) {  

System.out.println("onStartCommand");  

return super.onStartCommand(intent, flags, startId);  

    }  

@Override  

public void onDestroy() {  

System.out.println("onDestroy");  

super.onDestroy();  

    }  

}  

补充:(1):onstart()方法和onStartCommand()方法的区别:

onstart()方法是在android2.0一下的版本中使用。而在android2.0以上则使用onstartCommand()方法。它们两个方法放在一起使用时,不会产生冲突。


(2):onStartComand使用时,返回的是一个(int)整形。

这个整形可以有四个返回值:start_sticky、start_no_sticky、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY。

它们的含义分别是:

1):START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。

2):START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务

3):START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

4):START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。


(3)intentservice的用法

Android的Service阻塞时,通过Looper和Thread来解决标准Service中处理逻辑的阻塞问题。在android中,Service和activity是运行在同一个主线程中的。当其中的service程序出现睡眠5秒时,activity也会当机。

IntenService是service的子类,用来处理异步请求。客户端通过startService(Intent)方法传递请求给IntentService,IntentService通过worker thread处理每个intent对象,执行完后自动停止Service。

intentService需要实现两个方法:一个构造方法,复写一个onHandleIntent()方法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容

  • 【Android Service】 Service 简介(★★★) 很多情况下,一些与用户很少需要产生交互的应用程...
    Rtia阅读 3,134评论 1 21
  • 2.1 Activity 2.1.1 Activity的生命周期全面分析 典型情况下的生命周期:在用户参与的情况下...
    AndroidMaster阅读 3,010评论 0 8
  • Jianwei's blog 首页 分类 关于 归档 标签 巧用Android多进程,微信,微博等主流App都在用...
    justCode_阅读 5,888评论 1 23
  • 哎呀呀 ,马上就要面临找工作了,媛媛心里紧张呀. 作为一个即将毕业的Android程序媛,开始面临找工作了,...
    仇诺伊阅读 4,518评论 7 59
  • 昨天下午去参加孩子的家长会,结束后回家带了电脑和孩子,她背着自己的小提琴,我们一起去到漫猫咖啡厅准备晚上的活动。感...
    王五月阅读 409评论 0 1