1. 程式人生 > >Android 服務(service)的生命週期以及利用bindservice呼叫服務裡面的方法

Android 服務(service)的生命週期以及利用bindservice呼叫服務裡面的方法

服務的生命週期

服務的生命週期跟啟動服務的方法有關:
 當採用Context.startService()方法啟動服務,與之有關的生命週期方法
onCreate() onStart()  onDestroy()
onCreate()該方法在服務被建立時呼叫,該方法只會被呼叫一次,無論呼叫多少次startService()或bindService()方法,服務也只被建立一次。
onStart() 只有採用Context.startService()方法啟動服務時才會回撥該方法。該方法在服務開始執行時被呼叫。多次呼叫startService()方法儘管不會多次建立服務,但onStart() 方法會被多次呼叫。
onDestroy()該方法在服務被終止時呼叫。
 當採用Context.bindService()

方法啟動服務,與之有關的生命週期方法
onCreate() onBind()  onUnbind()  onDestroy()
onBind()只有採用Context.bindService()方法啟動服務時才會回撥該方法。該方法在呼叫者與服務繫結時被呼叫,當呼叫者與服務已經繫結,多次呼叫Context.bindService()方法並不會導致該方法被多次呼叫。
onUnbind()只有採用Context.bindService()方法啟動服務時才會回撥該方法。該方法在呼叫者與服務解除繫結時被呼叫。
如果先採用startService()方法啟動服務,然後呼叫bindService()方法繫結到服務,再呼叫unbindService()方法解除繫結,最後呼叫bindService()方法再次繫結到服務,觸發的生命週期方法如下:
onCreate()onStart()onBind()onUnbind()[過載後的方法需返回true]onRebind()

利用bindservice()呼叫服務裡面的方法:

開啟服務 (startservice) 
服務一旦開啟與呼叫者沒有任何的關係 , 呼叫著的activity 即便是退出了 不會影響。後臺的service的執行.在activity裡面 不能去呼叫服務裡面的方法 .

通過繫結方式開啟服務(bindservice)

服務跟呼叫者不求同生 ,但求同死.如果呼叫者(activity)退出了 那他繫結的服務呢 也會跟著退出.我們可以在activity裡面呼叫服務裡面的方法.利用 serviceSonnection 介面 返回一個ibinder物件 , 拿著ibinder物件獲取到服務裡面方法的引用(自定義了一個介面資訊) ,呼叫服

務裡面的方法 。


程式碼示例:

自定義介面IService.java:

package cn.itcast.servicelife;

public interface IService {
	public void callMethodInService();
}
MyService.java:
package cn.itcast.servicelife;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class MyService extends Service {
	// 初始化服務時執行
	@Override
	public IBinder onBind(Intent intent) {

		System.out.println("on bind");
		return new MyBinder();
	}

	public class MyBinder extends Binder implements IService {

		@Override
		public void callMethodInService() {
			sayHelloInService();
		}
	}

	/**
	 * 服務裡面的一個方法
	 */
	public void sayHelloInService() {
		System.out.println("hello in service");
	}

	@Override
	public boolean onUnbind(Intent intent) {
		System.out.println("on  unbind");
		return super.onUnbind(intent);
	}

	@Override
	public void onCreate() {
		System.out.println("oncreate");
		super.onCreate();
	}

	@Override
	public void onStart(Intent intent, int startId) {
		System.out.println("onstart");

		super.onStart(intent, startId);
	}

	@Override
	public void onDestroy() {
		System.out.println("ondestroy");
		super.onDestroy();
	}
}
DemoActivity.java:
package cn.itcast.servicelife;

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 DemoActivity extends Activity implements OnClickListener {

	Button bt_start;
	Button bt_stop;
	Button bt_bind_service; // 繫結服務
	Button bt_unbind_service; // 解除繫結服務
	Button bt_call_service;
	Intent intent;
	MyConn conn;
	IService iService;
	int flag = 0;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		bt_start = (Button) this.findViewById(R.id.button1);
		bt_stop = (Button) this.findViewById(R.id.button2);
		bt_bind_service = (Button) this.findViewById(R.id.button3);
		bt_unbind_service = (Button) this.findViewById(R.id.button4);
		bt_call_service = (Button) this.findViewById(R.id.button5);
		bt_start.setOnClickListener(this);
		bt_stop.setOnClickListener(this);
		bt_bind_service.setOnClickListener(this);
		bt_unbind_service.setOnClickListener(this);
		bt_call_service.setOnClickListener(this);
		intent = new Intent(this, MyService.class);
		conn = new MyConn();

	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.button1: // 開啟服務
			startService(intent);
			break;
		case R.id.button2: // 停止服務
			stopService(intent);
			break;
		case R.id.button3: // 繫結服務
			bindService(intent, conn, Context.BIND_AUTO_CREATE);
			break;
		case R.id.button4: // 解除繫結服務
			if (flag == 0) {
				Toast.makeText(getBaseContext(), "還沒有繫結服務,無需解綁", 0).show();
			} else {
				unbindService(conn);
				flag = 0;
			}
			break;
		// 繫結開啟
		case R.id.button5: // 呼叫服務裡面的方法
			iService.callMethodInService();
			break;
		}
	}

	private class MyConn implements ServiceConnection {

		// 繫結一個服務成功的時候 呼叫 onServiceConnected
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			flag = 1;
			iService = (IService) service;
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {

		}
	}

	// DemoActivity的銷燬方法
	@Override
	protected void onDestroy() {
		if (flag == 1) {
			unbindService(conn);
		}
		super.onDestroy();
	}
}
清單檔案:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.itcast.servicelife"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".DemoActivity"
            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" >
        </service>
    </application>

</manifest>

問題  ????????????

1.通過實驗證明在bindService之後在模擬器的設定中的“正在執行的服務”中找不到相應的服務,是因為和activity繫結的所以不顯示嗎?

2.在unbindService之後還可以呼叫服務裡面的方法,為什麼?服務不是已經被銷燬了嗎?