Android-Service生命周期

时间:2023-03-08 18:21:24

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的生命周期:

先来一张经典的生命周期图示:

Android-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>

之后执行结果:

Android-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>

之后执行结果:

Android-Service生命周期

从log中也可以看出,在Activity中多次执行bindService()也没有重复执行onBind()