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之後還可以呼叫服務裡面的方法,為什麼?服務不是已經被銷燬了嗎?