Android Service介紹與實作

1.什麼是Android Service
  • Android Service,是一種在後臺運行並可與系統互動的一支程式。它跟Activity 的功能差不多,但是他不能自己運作,需要通過某一個Activity 或者其他Context 物件來執行(例如 :Context.startService() 和 Context.bindService() )。
  • 這裏說明一下如果你在Service 的onCreate 或者onStart 做一些很耗時間的事情,最好在Service 裏啟動一個執行緒完成,因為Service 是跑在主執行緒中,會影響到你的UI 操作或是阻擋主執行緒中的其他程式。
  • 什麼時候需要Service 呢?例如播放多媒體的時候啟動了其他Activity 這個時候程式要在後臺繼續播放,比如檢測SD 卡上檔案的變化,或者是記錄你地理資訊位置的改變等等。
2. Service 的生命週期程序
  • Service 的生命週期方法比Activity 少一些,只有onCreate, onStart, onDestroy我們有兩種方式啟動一個Service,他們對Service 生命週期的影響是不一樣的。
       1.通過startService
                      Start 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 視窗效果如下圖:


  • 我們這時可以按HOME 鍵進入Settings(設置)->Applications(應用程式)->RunningServices(正在運行的服務)看一下我們新啟動了一個服務,效果如下:


  • 點擊stopService 按鈕時,Service 則執行了onDestroy()方法,效果圖如下所示:

  • 這時候我們再次點選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>

沒有留言: