学习android之Service

综述

Service是android 系统中的一种组件,它跟Activity的级别差不多,但是他不能自己运行,只能后台运行,并且可以和其他组件进行交互。service可以在很多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务嘛,总是藏在后头的。

启动方式

1 .context.startService() 方式

使用context.startService() 启动时,Service会经历如下生命周期:

Start:  context.startService()→onCreate()→onStart()→Servicerunning

Stop:  context.stopService()→onDestroy()→Service stop

如果Service还没有运行,则android先调用onCreate()然后调用onStart();如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。 stopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service。所以调用startService的生命周期为:onCreate --> onStart(可多次调用)--> onDestroy

2. context.bindService()方式

使用使用context.bindService()启动时,Service会经历如下生命周期:

Start:  context.bindService()→onCreate()→onBind()→Servicerunning

Stop:  onUnbind()→onDestroy()→Service stop

onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。 所以调用bindService的生命周期为:onCreate->onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。

编程流程:

1.     注册Service,在AndroidManifest.xml 文件中定义。

2.     编写自己的Service类,该类必须继承Service类

3.     在适当的位置启动Service。

举例1 音乐播放

MainActivity:PlayService.java
package com.example.com.njupt.zhb.musicplay;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.view.View.OnClickListener;
publicclass PlayService extends Activity {
private Button PlayBtn;
private Button StopBtn;
OnClickListener listener=null;
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_service);
PlayBtn=(Button)findViewById(R.id.start);
StopBtn=(Button)findViewById(R.id.stop);
listener=new View.OnClickListener() {

@Override
publicvoid onClick(View v) {
// TODO Auto-generatedmethod stub
switch(v.getId()){
case R.id.start:
//启动在manifest.xml中注册为“blog.csdn.net.nuptboyzhb.StartService”的Service
Intentintent1=newIntent("blog.csdn.net.nuptboyzhb.StartService");

break;
case R.id.stop:
//停止在manifest.xml中注册为“blog.csdn.net.nuptboyzhb.StartService”的Service
Intentintent2=new Intent("blog.csdn.net.nuptboyzhb.StartService");

break;
}
}
};
PlayBtn.setOnClickListener(listener);
StopBtn.setOnClickListener(listener);
}

@Override
publicboolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.activity_play_service, menu);
returntrue;
}
}
Service :Music.java
package com.example.com.njupt.zhb.musicplay;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;
publicclass Music extends Service {
private MediaPlayer player;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generatedmethod stub
returnnull;
}
@Override
publicvoidonStart(Intentintent, int startId) {
super.onStart(intent, startId);
player = MediaPlayer.create(this, R.raw.gequ);
player.start();
Log.e("1","play");
}
@Override
publicvoidonDestroy()
super.onDestroy();
player.stop();
Log.e("2","stop");
}
}
XML :activity_play_service.xml
<?xml version="1.0"encoding="utf-8"?>
<AbsoluteLayout
android:id="@+id/widget0"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="@+id/start"
android:layout_width="319dp"
android:layout_height="wrap_content"
android:text="Play"
android:layout_x="1dp"
android:layout_y="45dp"/>
<Button
android:id="@+id/stop"
android:layout_width="317dp"
android:layout_height="wrap_content"
android:text="Stop"
android:layout_x="2dp"
android:layout_y="99dp"/>
</AbsoluteLayout>
XML :AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.com.njupt.zhb.musicplay"
android:versionCode="1"
android:versionName="1.0">

<uses-sdk
android:minSdkVersion="4"
android:targetSdkVersion="15"/>

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".PlayService"
android:label="@string/title_activity_play_service">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<! 注册service>
<serviceandroid:name=".Music">
<intent-filter>
<actionandroid:name="blog.csdn.net.nuptboyzhb.StartService"/>
<categoryandroid:name="android.intent.category.default"/>
</intent-filter>
</service>
</application>
</manifest>

小节

从上述代码中,我们应该注意如下几点:

1.      startService和stopService的Intent的参数,必须与AndroidManifest.xml文件中action项的name值保持完全一致。否则,不能启动Music服务。

2.     服务Music必须继承Service类。