Android-Service生命周期
Service的基本概念,以及Service的生命周期:
一、Service的基本概念:
一个Service就是应用程序的组件,可以在后台长期跑,或者是为其他的应用提供功能上的支持。Service一般与Activity相对理解,它是没有Activity的界面的,Service也具有自己的独特生命周期,一个Service需要在AndroidManifest.xml中进行配置,
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.li.xiami.ServiceActivity1"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".StartActivity"></service>
</application>
注意:这个里面也可以增加android:process=".remote"来设置是远程调用,然后就是remote service
可以通过Context.startService()或者是Context.bindService()来启动Service;service是跑在宿主进程的主线程中,那么如果你的service需要做消耗CPU或者是阻塞的操作,那么应该重新开一个线程来处理这些耗时的操作。IntentService是继承自Service的,它会帮你重开一个线程来执行耗时操作。
注:Service既不是一个独立的进程,也不是一个线程,其实Service就是两个特性,也是跟生命周期结合起来的,一个是能够在后台一直跑,可以通过startService启动,一个是能够与其他应用进行交互,通过bindService建立连接,进行通信
Service具体的实现有两种,一个是localService,一个是通过AIDL来实现remoteService。
二、Service的生命周期:
先来一张经典的生命周期图示:

所涉及到的所有跟Service相关的函数包括:
onCreate()——Create只执行一次
onStartCommand()——可以多次执行
onDestory()——只执行一次
onBind()——绑定也只执行一次
onUnBind()——解绑也只执行一次
startService的生命周期:
onCreate()-onStartCommand()-onDestory():startService的时候会调onCreate(),但是只调一次,onStartCommand()可以被调用多次
StartService的程序实现:
package com.li.xiami; import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log; public class startService extends Service { private final String tag = "service"; @Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
} @Override
public void onCreate() {
// TODO Auto-generated method stub
Log.v(tag, "onCreate()");
super.onCreate();
} @Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.v(tag, "onDestory()");
super.onDestroy();
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.v(tag, "onStartCommand()");
return super.onStartCommand(intent, flags, startId);
} }
package com.li.xiami; import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast; public class MainActivity extends Activity { private Button buttonstart;
private Button buttonstop;
private Button buttonsecondstart; private final String tag = "Activity"; Intent intent = new Intent(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); buttonstart = (Button) findViewById(R.id.buttonstartservice);
buttonstop = (Button) findViewById(R.id.buttonstopservice);
buttonsecondstart = (Button) findViewById(R.id.buttonsencondstart); intent.setClass(MainActivity.this, startService.class); buttonstart.setOnClickListener(onClick);
buttonstop.setOnClickListener(onClick);
buttonsecondstart.setOnClickListener(onClick); } //这个匿名内部类的统一实现,要放在onCreate()的外面,这样这个先被初始化,然后onCreate()里面的button就能够找到这个对象
View.OnClickListener onClick = new View.OnClickListener() { @Override
public void onClick(View v) {
//switch里面写v.getId()。。。
switch(v.getId()){
case R.id.buttonstartservice:
//Toast.makeText().show()——之前只makeText了,也没有show()啊,笨蛋!!!
Toast.makeText(MainActivity.this, "startService", Toast.LENGTH_SHORT).show();
startService(intent);
Log.v(tag, "start service");
break;
case R.id.buttonstopservice:
Toast.makeText(MainActivity.this, "stopService", Toast.LENGTH_SHORT).show();
stopService(intent);
Log.v(tag, "stop service");
break; case R.id.buttonsencondstart:
Toast.makeText(getApplicationContext(), "secondStartService", Toast.LENGTH_SHORT).show();
startService(intent);
Log.v(tag, "second start service");
break; }
}
}; @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }
AndroidManifest.xml中注册Service:
<service android:name=".startService"></service>
之后执行结果:

从startService的生命周期的运行log中就可以看到,Activity中执行startService()之后,Service执行回调函数onCreate()-onStartCommand(),之后再进行一次startService的话,只会执行onStartCommand(),Activity中执行stopService()的话,Service直接执行onDestory()。
Unbounded service:
bindService()的生命周期:
onCreate()-onBind()-onUnBind()-onDestory(),所有都是只执行一次,onBind()函数也是只执行一次
bindService的程序实现:(通过IBinder接口来实现,在Service中实现一个继承自Binder的类,然后在onBind()中返回一个Binder的对象,在Activity中通过得到这个Binder对象来进行通信)
package com.li.xiami; import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log; public class BindService extends Service { public final String tag = "service"; public class MyBinder extends Binder{
String state = "绑定绑定获取binder的数据";
String getState(){
return state;
}
} MyBinder mybinder = new MyBinder(); @Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.v(tag, "onBind()");
return mybinder;
} @Override
public void onCreate() {
// TODO Auto-generated method stub
Log.v(tag, "onCreate()");
super.onCreate();
} @Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.v(tag, "onDestory()");
super.onDestroy();
} @Override
@Deprecated
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
Log.v(tag, "onStart()");
super.onStart(intent, startId);
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.v(tag, "onStartCommand()");
return super.onStartCommand(intent, flags, startId);
} @Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
Log.v(tag, "onUnBind()");
return super.onUnbind(intent);
} }
package com.li.xiami; import com.li.xiami.BindService.MyBinder; import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast; public class MainActivity extends Activity { private Button buttonbind;
private Button buttongetstate;
private Button buttonunbind; Intent intent = new Intent();
BindService.MyBinder mybinder = null; private final String tag = "Activity"; boolean isBound = false; ServiceConnection conn = new ServiceConnection(){ @Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
mybinder = (MyBinder) service;
} @Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
mybinder = null;
} }; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); buttonbind = (Button) findViewById(R.id.buttonbind);
buttongetstate = (Button) findViewById(R.id.buttongetstate);
buttonunbind = (Button) findViewById(R.id.buttonunbind); intent.setClass(MainActivity.this, BindService.class); buttonbind.setOnClickListener(onClick);
buttongetstate.setOnClickListener(onClick);
buttonunbind.setOnClickListener(onClick); } View.OnClickListener onClick = new View.OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.buttonbind:
Log.v(tag, "bindservice");
bindService(intent, conn, Service.BIND_AUTO_CREATE);
Toast.makeText(getApplicationContext(), "绑定服务", Toast.LENGTH_SHORT).show();
isBound = true;
break;
case R.id.buttongetstate:
Log.v(tag, "getstate");
if(isBound == true){
Toast.makeText(getApplicationContext(), "获取服务状态:"+mybinder.getState(), Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), "还没绑定,请绑定", Toast.LENGTH_SHORT).show();
}
break;
case R.id.buttonunbind:
if(isBound == true){
Log.v(tag, "unbind");
Toast.makeText(getApplicationContext(), "解除绑定", Toast.LENGTH_SHORT).show();
unbindService(conn);
isBound = false;
}
else{
Toast.makeText(getApplicationContext(), "还没绑定,请绑定", Toast.LENGTH_SHORT).show();
}
break;
}
}
}; @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }
AndroidManifest.xml中注册Service:
<service android:name=".BindService"></service>
之后执行结果:

从log中也可以看出,在Activity中多次执行bindService()也没有重复执行onBind()
Android-Service生命周期的更多相关文章
- Android Service生命周期及用法
Service概念及用途:Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行, ...
- Android Service 生命周期
Service概念及用途: Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行 ...
- Android Service 生命周期和使用注意项
一.基础知识 服务一般分为两种: 1:本地服务, Local Service 用于应用程序内部.在Service可以调用Context.startService()启动,调用Context.stopS ...
- 对于Android Service 生命周期进行全解析
应用程序组件有一个生命周期——一开始Android实例化他们响应意图,直到结束实例被销毁.在这期间,他们有时候处于激活状态,有时候处于非激 活状态:对于活动,对用户有时候可见,有时候不可见.组件生命周 ...
- Android Service生命周期 Service里面的onStartCommand()方法详解
在Demo上,Start一个Service之后,执行顺序:onCreate - > onStartCommand 然后关闭应用,会重新执行上面两步. 但是把代码拷贝到游戏工程发现,关闭游戏后,只 ...
- Service 生命周期
有了 Service 类我们如何启动他呢,有两种方法: • Context.startService() • Context.bindService() 1. 在同一个应用任何地方调用 start ...
- Android生命周期和Service生命周期
android生命周期 运行:oncreate → onstart → onresume暂停:onresume → onpause:再次运行:onresume停止:onpause → onstop → ...
- Android(java)学习笔记171:Service生命周期
1.Service的生命周期 Android中的Service(服务)与Activity不同,它是不能和用户交互,不能自己启动的,运行在后台的程序,如果我们退出应用的时候,Servic ...
- Android中startService的使用及Service生命周期
Android中有两种主要方式使用Service,通过调用Context的startService方法或调用Context的bindService方法.本文仅仅探讨纯startService的使用.不 ...
- Android(java)学习笔记114:Service生命周期
1.Service的生命周期 Android中的Service(服务)与Activity不同,它是不能和用户交互,不能自己启动的,运行在后台的程序,如果我们退出应用的时候,Servic ...
随机推荐
- Spring JSR-250注解
Java EE5中引入了“Java平台的公共注解(Common Annotations for the Java Platform)”,而且该公共注解从Java SE 6一开始就被包含其中. 2006 ...
- java 线程的优先级
//线程的优先级 //线程1 class xc1 implements Runnable{ public void run(){ for(int i=0;i<20;i++){ System.ou ...
- 开源是一种态度、分享是一种精神 — FirApi发布、WeiXinApi更新
在云计算盛行的年代,接触开发式的平台必不可少,因项目累积的代码也不少,之前本着"重复的事情自己做一次就够了,不需要其他人在重复为此工作."的想法发布了WeiXinApi.Boots ...
- buildbot的codebaseGenerator
buildbot的codebaseGenerator文档非常简单,简单到令人发指. 也没有一个例子,唉,辛苦了好几个小时才研究清楚怎么设置. 赶紧记录下吧,不然下次又要纠结. 应用场景:web sta ...
- Codeforces 723c [贪心][乱搞]
/* 不要低头,不要放弃,不要气馁,不要慌张. 题意: 给一个n和m. 第二行给n个数. 每次操作可以把n个数中的任何一个数替代为别的数,问最少的操作次数使得1.2.3.4.5...m中的数出现的次数 ...
- sp_help 快速查看表结构、视图信息
sp_helptext: 是MS SQL Server的一个系统存储过程,可以通过它来查看存储过程或者视图.函数源码 示例:sp_helptext viewName (viewName 即要查询的存 ...
- XE6移动开发环境搭建之IOS篇(9):配置XE6的IOS SDK(有图有真相)
网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 1.开启PAServ ...
- Fping
(十大特色功能) Ping是最常用的网络测试工具,ping的测试功能其实比较多,xp系统的ping有12个选项.但是,fping测试工具有25个选项,在ping的基础上增加了许多专业的功能,可用于更深 ...
- EXT学习之——Ext下拉框绑定无效的问题
1.保证store定义是否在combobox前面 2.有没写 .load 3.有没赋值 xxstore:xxstore 具体看详细步骤 http://www.cnblogs.com/wdw3121 ...
- HtmlAgilityPack下载开启压缩的页面乱码
当一个被采集的网页是开启压缩了的话,如果使用HtmlAgilityPack 的HtmlWeb默认配置去下载,下载回来的HTML代码是乱码,应该进行如下操作 HtmlWeb web = new Html ...