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的程序实现:
1 package com.li.xiami; 2 3 import android.app.Service; 4 import android.content.Intent; 5 import android.os.IBinder; 6 import android.util.Log; 7 8 public class startService extends Service { 9 10 private final String tag = "service"; 11 12 @Override 13 public IBinder onBind(Intent intent) { 14 // TODO Auto-generated method stub 15 return null; 16 } 17 18 @Override 19 public void onCreate() { 20 // TODO Auto-generated method stub 21 Log.v(tag, "onCreate()"); 22 super.onCreate(); 23 } 24 25 @Override 26 public void onDestroy() { 27 // TODO Auto-generated method stub 28 Log.v(tag, "onDestory()"); 29 super.onDestroy(); 30 } 31 32 @Override 33 public int onStartCommand(Intent intent, int flags, int startId) { 34 // TODO Auto-generated method stub 35 Log.v(tag, "onStartCommand()"); 36 return super.onStartCommand(intent, flags, startId); 37 } 38 39 }
1 package com.li.xiami; 2 3 import android.os.Bundle; 4 import android.app.Activity; 5 import android.content.Intent; 6 import android.util.Log; 7 import android.view.Menu; 8 import android.view.View; 9 import android.widget.Button; 10 import android.widget.Toast; 11 12 public class MainActivity extends Activity { 13 14 private Button buttonstart; 15 private Button buttonstop; 16 private Button buttonsecondstart; 17 18 private final String tag = "Activity"; 19 20 Intent intent = new Intent(); 21 22 @Override 23 protected void onCreate(Bundle savedInstanceState) { 24 super.onCreate(savedInstanceState); 25 setContentView(R.layout.activity_main); 26 27 buttonstart = (Button) findViewById(R.id.buttonstartservice); 28 buttonstop = (Button) findViewById(R.id.buttonstopservice); 29 buttonsecondstart = (Button) findViewById(R.id.buttonsencondstart); 30 31 intent.setClass(MainActivity.this, startService.class); 32 33 buttonstart.setOnClickListener(onClick); 34 buttonstop.setOnClickListener(onClick); 35 buttonsecondstart.setOnClickListener(onClick); 36 37 } 38 39 //这个匿名内部类的统一实现,要放在onCreate()的外面,这样这个先被初始化,然后onCreate()里面的button就能够找到这个对象 40 View.OnClickListener onClick = new View.OnClickListener() { 41 42 @Override 43 public void onClick(View v) { 44 //switch里面写v.getId()。。。 45 switch(v.getId()){ 46 case R.id.buttonstartservice: 47 //Toast.makeText().show()——之前只makeText了,也没有show()啊,笨蛋!!! 48 Toast.makeText(MainActivity.this, "startService", Toast.LENGTH_SHORT).show(); 49 startService(intent); 50 Log.v(tag, "start service"); 51 break; 52 case R.id.buttonstopservice: 53 Toast.makeText(MainActivity.this, "stopService", Toast.LENGTH_SHORT).show(); 54 stopService(intent); 55 Log.v(tag, "stop service"); 56 break; 57 58 case R.id.buttonsencondstart: 59 Toast.makeText(getApplicationContext(), "secondStartService", Toast.LENGTH_SHORT).show(); 60 startService(intent); 61 Log.v(tag, "second start service"); 62 break; 63 64 } 65 } 66 }; 67 68 69 @Override 70 public boolean onCreateOptionsMenu(Menu menu) { 71 // Inflate the menu; this adds items to the action bar if it is present. 72 getMenuInflater().inflate(R.menu.main, menu); 73 return true; 74 } 75 76 }
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对象来进行通信)
1 package com.li.xiami; 2 3 import android.app.Service; 4 import android.content.Intent; 5 import android.os.Binder; 6 import android.os.IBinder; 7 import android.util.Log; 8 9 public class BindService extends Service { 10 11 public final String tag = "service"; 12 13 public class MyBinder extends Binder{ 14 String state = "绑定绑定获取binder的数据"; 15 String getState(){ 16 return state; 17 } 18 } 19 20 MyBinder mybinder = new MyBinder(); 21 22 @Override 23 public IBinder onBind(Intent intent) { 24 // TODO Auto-generated method stub 25 Log.v(tag, "onBind()"); 26 return mybinder; 27 } 28 29 @Override 30 public void onCreate() { 31 // TODO Auto-generated method stub 32 Log.v(tag, "onCreate()"); 33 super.onCreate(); 34 } 35 36 @Override 37 public void onDestroy() { 38 // TODO Auto-generated method stub 39 Log.v(tag, "onDestory()"); 40 super.onDestroy(); 41 } 42 43 @Override 44 @Deprecated 45 public void onStart(Intent intent, int startId) { 46 // TODO Auto-generated method stub 47 Log.v(tag, "onStart()"); 48 super.onStart(intent, startId); 49 } 50 51 @Override 52 public int onStartCommand(Intent intent, int flags, int startId) { 53 // TODO Auto-generated method stub 54 Log.v(tag, "onStartCommand()"); 55 return super.onStartCommand(intent, flags, startId); 56 } 57 58 @Override 59 public boolean onUnbind(Intent intent) { 60 // TODO Auto-generated method stub 61 Log.v(tag, "onUnBind()"); 62 return super.onUnbind(intent); 63 } 64 65 }
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()