Service是Android系统中类似于Activity的一种组件,不能自己启动,也不能与用户交互,只能运行于后台。比如后台运行的音乐播放器。
Service的生命周期有三,onCreate()=》onStart()=》onDestory()。启动后只能调用onStart()。
Service分为两种:
本地服务(Local Service):用于应用程序内部。用于实现应用程序耗时操作,现成独立,可提升用户体验。
远程服务(Remote Service):用于Android系统内部的应用程序之间。用于程序共享服务,如天气预报,其他应用程序只用调用已有的即可。
实现Service需要继承Service类,启动方式有两种:
startService()启动的服务,调用者和服务之间没有关联,即便调用者退出了,服务仍然运行。结束方式为stopService。
bindService()启动的服务是把调用者和服务绑定在一起,调用者一旦退出,服务也终止了。对应的结束方式为unbindService()。
下面进入代码实战,以一每秒递增的计数器为例,分别针对startService和bindService启动方式的两种service
startService方式的Service使用:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".LocalStartServiceActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".CountStartService"></service>
</application>
</manifest>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<Button
android:id="@+id/myButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/start"
/>
</LinearLayout>
服务类CountStartService.java
package com.android;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class CountStartService extends Service {
private boolean threadDisable;//默认false
private int count;//默认0
@Override
public IBinder onBind(Intent arg0) {
return null;
}
public void onCreate(){
super.onCreate();
new Thread(new Runnable() {
public void run() {
while(!threadDisable){
try{
Thread.sleep(1000);
}catch(Exception e){
}
count++;
Log.v("start", "Count to "+getCount());
}
}
}).start();
}
public void onDestroy(){
super.onDestroy();
this.threadDisable=true;
}
public int getCount(){
return count;
}
}
启动服务的视图LocalStartServiceActivity.java
package com.android;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class LocalStartServiceActivity extends Activity {
/** Called when the activity is first created. */
private Button startbutton;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startbutton = (Button)findViewById(R.id.myButton);
startbutton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(LocalStartServiceActivity.this,CountStartService.class);
startService(intent);
}
});
Log.v("start", "onCreate()");
}
protected void onDestroy()
{
super.onDestroy();
Intent intent = new Intent(LocalStartServiceActivity.this,CountStartService.class);
stopService(intent);
Log.v("start", "onDestroy(");
}
}
startService 启动的Service是比较简单的一种启动方式,需要手动stopService来关闭。
接下来是bindService方式调用服务。
服务类CountBindService.java
package com.android;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class CountBindService extends Service {
private boolean threadDisable;
private int count;
private ServiceBinder serviceBinder=new ServiceBinder();
public IBinder onBind(Intent intent) {
return serviceBinder;
}
public void onCreate()
{
super.onCreate();
new Thread(new Runnable(){
public void run() {
while(!threadDisable){
try{
Thread.sleep(1000);
}catch(Exception e){
}
count++;
Log.v("lzp", "Count to "+getCount());
}
}}).start();
}
public int getCount(){
return this.count;
}
public void onDestroy()
{
super.onDestroy();
threadDisable = true;
}
public void doSomething()
{
Log.v("bindservice", "do something");
}
class ServiceBinder extends Binder{
public CountBindService getServices(){
return CountBindService.this;
}
}
}
调用service的视图LocalBindServiceActivity
package com.android;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import com.android.CountBindService.ServiceBinder;
public class LocalBindServiceActivity extends Activity{
private CountBindService countService;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.v("bindservice", "into");
Intent intent = new Intent(LocalBindServiceActivity.this,CountBindService.class);
bindService(intent, conn, Context.BIND_AUTO_CREATE);//启动服务
}
protected void onDestroy()
{
super.onDestroy();
this.unbindService(conn);//解除
Log.v("bindservice", "out");
}
private ServiceConnection conn = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
countService = null;
}
public void onServiceConnected(ComponentName name, IBinder service) {
countService = ((ServiceBinder)service).getServices();\\获取服务对象
countService.doSomething();
}
};
}
bindService调用服务不是很复杂,要实现服务与调用者之间的通信是有几点值得注意的:
a)必须实现onBind方法的回调,返回的对象是在服务类的内部类(继承Binder并且返回当前服务)。
b)调用者须通过bindService依赖于ServiceConnection对象,当然bindService也是启动服务的方法;之后服务连接后,ServiceConnection里可获取服务对象,可调用服务的方法,实现通信。
当然service的两种调用的实现方式多种多样,想要看更牛的关于service的文章,可以去http://rainbow702.iteye.com/blog/1144521 。
后续研究深入会在service这块添新文章,欢迎拍砖。