- Android Service,是一種在後臺運行並可與系統互動的一支程式。它跟Activity 的功能差不多,但是他不能自己運作,需要通過某一個Activity 或者其他Context 物件來執行(例如 :Context.startService() 和 Context.bindService() )。
- 這裏說明一下如果你在Service 的onCreate 或者onStart 做一些很耗時間的事情,最好在Service 裏啟動一個執行緒完成,因為Service 是跑在主執行緒中,會影響到你的UI 操作或是阻擋主執行緒中的其他程式。
- 什麼時候需要Service 呢?例如播放多媒體的時候啟動了其他Activity 這個時候程式要在後臺繼續播放,比如檢測SD 卡上檔案的變化,或者是記錄你地理資訊位置的改變等等。
- Service 的生命週期方法比Activity 少一些,只有onCreate, onStart, onDestroy我們有兩種方式啟動一個Service,他們對Service 生命週期的影響是不一樣的。
1.通過startServiceStart Service 會經歷 onCreate -> onStart,stopService 的時候直接onDestroy
如果是使用者自己直接退出而沒有使用stopService 的話,Service 會一直在後臺運 行。下次主程式起來時可以再stopService。
2.通過bindService
Service 只會運行onCreate-> onBind, 這個時候主程式和Service 結合在一起
主程式退出了,Service 就會使用onUnbind->onDestroyed。
3.Service 與Activity 通訊:
- Service 的資料最終還是要呈現在前端Activity 之上,因為啟動Service 時,系統會重新開啟一個新的程式,當我們想獲取啟動的Service 物件參考時,我們可以用bindService 和unbindService 方法,它們分別執行了Service 中onBind ()和onUnbind()方法。點選startServie 按鈕時先後執行了Service 中onCreate()->onStart()這兩個方法,打開Logcat 視窗效果如下圖:
- 這時候我們再次點選startService 按鈕,然後點選bindService 按鈕(通常bindService 都是bind 已經啟動的Service),我們看一下Service 執行了onBind()方法,以及TextView 的值也有所變化了,如下兩張圖所示:
- 最後點選unbindService 按鈕,則Service 執行了onUnbind()方法,如下圖所示:
以下為實作範例
1.UI的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" >
<Button
android:id="@+id/btnStartService"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Start Service" />
<Button
android:id="@+id/btnStopService"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Stop Service" />
<Button
android:id="@+id/btnBindService"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Bind Service" />
<Button
android:id="@+id/btnUnbindService"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Unbind Service" />
</LinearLayout>
2.MyService.java
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private MyBinder myBinder = new MyBinder();
@Override
public IBinder onBind(Intent intent) {
Log.d("MyService", "onBind");
return myBinder;
}
@Override
public void onCreate() {
Log.d("MyService", "onCreate");
super.onCreate();
}
@Override
public void onDestroy() {
Log.d("MyService", "onDestroy");
super.onDestroy();
}
@Override
public void onRebind(Intent intent) {
Log.d("MyService", "onRebind");
super.onRebind(intent);
}
@Override
public void onStart(Intent intent, int startId) {
Log.d("MyService", "onStart");
super.onStart(intent, startId);
}
@Override
public boolean onUnbind(Intent intent) {
Log.d("MyService", "onUnbind");
return super.onUnbind(intent);
}
public class MyBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
}
3.Main.java
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.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class Main extends Activity implements OnClickListener {
private Intent serviceIntent;
private MyService myService;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
myService = null;
Toast.makeText(Main.this, "Service Failed.", Toast.LENGTH_LONG)
.show();
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myService = ((MyService.MyBinder) service).getService();
Toast.makeText(Main.this, "Service Connected.", Toast.LENGTH_LONG)
.show();
}
};
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnStartService:
startService(serviceIntent);
break;
case R.id.btnStopService:
stopService(serviceIntent);
break;
case R.id.btnBindService:
bindService(serviceIntent, serviceConnection,
Context.BIND_AUTO_CREATE);
break;
case R.id.btnUnbindService:
unbindService(serviceConnection);
break;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnStartService = (Button) findViewById(R.id.btnStartService);
Button btnStopService = (Button) findViewById(R.id.btnStopService);
Button btnBindService = (Button) findViewById(R.id.btnBindService);
Button btnUnbindService = (Button) findViewById(R.id.btnUnbindService);
btnStartService.setOnClickListener(this);
btnStopService.setOnClickListener(this);
btnBindService.setOnClickListener(this);
btnUnbindService.setOnClickListener(this);
serviceIntent = new Intent(this, MyService.class);
}
}
4.AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.activity.service"
android:versionCode="1"
android:versionName="1.0" >
<application
android:icon="@drawable/icon"
android:label="@string/app_name" >
<activity
android:name=".Main"
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="MyService"
android:enabled="true" />
</application>
<uses-sdk android:minSdkVersion="10" />
</manifest>
沒有留言:
張貼留言