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 ...
随机推荐
- 转 通过js获取cookie的实例及简单分析
今天review新人写的javascript代码的时候发现了很多的问题.这里以function getCookie(name){}为例. 其中比较典型的一个问题就是如何通过javascript获取co ...
- Python学习笔记——Day4
字符串操作 string典型的内置方法: count() center() startswith() find() format() lower() upper() strip() replace() ...
- 通过反射得到object[]数组的类型并且的到此类型所有的字段及字段的值
private string T_Account(object[] list) { StringBuilder code = new StringBuilder(); //得到数据类型 Type t ...
- RabbitMQ 安装
Install Erlang from the Erlang Solutions repository or Follow the instructions under "Installat ...
- linux网络环境下socket套接字编程(UDP文件传输)
今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中, ...
- iOS学习-----真机测试过程
原文 http://www.th7.cn/Program/IOS/201407/233103.shtml 1:进入苹果开发者平台 2:进入Member Center 3:输入开发者账号和密码 4: ...
- 【Oozie】安装配置Oozie
安装和配置Oozie Oozie用于Hadoop的工作流配置: 参考链接: <Install and Configure Apache Oozie Workflow Scheduler for ...
- .NET:序列化和反序列化
.NET:序列化和反序列化 需要反序列化的字符串: { "LouPanID": "sample string 1", "LouPanHao" ...
- 【总结】我所整理的各种CSS居中
在网上看了很多文章,自己也总结了一下,虽说是自己写的,但是还是要列出我参考过的那些文章的地址,感谢你们的分享! http://blog.gejiawen.com/2015/03/13/css-lay ...
- 使用属性动画简单实现view飞入效果
比较简单的效果,可以用来菜单飞入之类,作为记录吧, package com.test.animation; import android.app.Activity; import android.os ...