Android組件之 Service

一、Service初步瞭解

        Service是Android中四大組件之一,用來進行後臺處理時間長的任務操作,可以避免Android的ANR。最爲經典的使用場景是在音樂播放器中,使用Service可以使音樂在後臺播放,即使我們離開播放器APP音樂也不會停止。Service+Notification+Broadcast Receive三者聯合使用將會得到意想不到的用戶體驗。作爲組件,Service需要在Manifirst.xml文件中進行註冊。

       想要使用Service服務必須繼承android.app.Service類,主要處理其中的以下方法:

public class MyStartService extends Service {
	
	public void onCreate() {
		super.onCreate();
	}
	
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
	}
	
	public int onStartCommand(Intent intent, int flags, int startId) {
		return super.onStartCommand(intent, flags, startId);
	}

	public IBinder onBind(Intent intent) {
		return null;
	}

        public boolean onUnbind(Intent intent) {
               return super.onUnbind(intent);
        }

        public void onDestroy() {
		super.onDestroy();
	}

}



二、Service的兩種啓動方式

       1、startService():Context組件通過調用此方法可以啓動一個Service,此時啓動的服務不收Context組件的生命週期的影響。也就是說當啓動服務的組件銷燬後,服務依然存在。此時Service的生命週期相關的函數是onCreat()、onStart()、onStartCommand()、onDestory();

startService()開始服務:

stopService()停止服務:

當我們多次startService()時,onCreate()只會調用一次,而onStart()和onStartCommand()可以多次調用,不管調用多少次startService(),我們只需要使用一次stopService()就可以將服務銷燬,以下是我們進行3次啓動1次銷燬的log日誌:


      

        2、bindService():Context組件通過調用此方法可以綁定一個Service,當啓動它的組件銷燬時,其綁定的服務也會一起銷燬,有種愛叫做不求同生,但願同死的趕腳。在啓動組件銷燬前,我們必須要保證它與綁定的服務間要有解綁動作,不然Android系統會報錯誤。在進行綁定時會涉及到一個ServiceConnection類,當綁定成功時會回調其中的onServiceConnected()方法。

        在進行綁定服務的時候相關的生命週期方法是:onCreate()、onBind()、onUnbind()、onDestory();

bindService()綁定服務:

unBindService()解除綁定:

多次調用bindService()綁定服務時,不會重複調用生命週期函,一下是3次綁定1次解除綁定的log:

三、同時使用兩種方式來啓動Service服務

        當我們同時使用了startService()開始服務和bindService()綁定服務時,必須調用一次stopService()和unBindService()才能夠銷燬一個服務。大家跟着我的操作來一起看看log日誌:


操作步驟:

1、startService()開始服務

2、bindService()綁定服務

3、startService()開始服務

4、bindService()綁定服務

5、stopService()服務

6、startService()開始服務

7、startService()開始服務

8、stopService()服務

9、unBindService()服務

源代碼部分:

Activity代碼:

public class SjcServiceActivity extends Activity {
	
	Intent startServiceIntent;
	ServiceConnection connection;
	boolean isBindService = false;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_service);
		
		startServiceIntent = new Intent(this, MyStartService.class);
		connection = new ServiceConnection() {
			
			//當綁定的服務崩潰或被殺死導致的連接中斷時被調用,自己解除綁定時則不會被調用
			public void onServiceDisconnected(ComponentName name) {
				Log.i("TAG", "MyStartService --> onServiceDisconnected");
				unBindServie();
			}
			
			//當綁定服務時會調用這個方法
			public void onServiceConnected(ComponentName name, IBinder service) {
				isBindService = true;
				Log.i("TAG", "MyStartService --> onServiceConnected");
			}
		};
	}
	
	protected void onDestroy() {
		super.onDestroy();
		unBindServie();//當Activity銷燬時,必須解除所綁定的服務,不然會報錯
	}
	
	
	public void onClick(View v) {
		
		Button btn = (Button)v;
		
		switch (v.getId()) {
		case R.id.btn_startService:
			startService(startServiceIntent);
			break;
			
		case R.id.btn_stopService:
			stopService(startServiceIntent);
			break;
			
		case R.id.btn_bindService:
			bindService(startServiceIntent, connection, Context.BIND_AUTO_CREATE);
			break;
			
		case R.id.btn_unbindService:
			unBindServie();
			break;

		default:
			Toast.makeText(this, btn.getText(), Toast.LENGTH_SHORT).show();
			break;
		}
	}
	
	private void unBindServie() {
		if(isBindService) {
			isBindService = false;
			unbindService(connection);
		} 
	}
}

Activity的佈局xml文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_gravity="center"
        >
        
        <Button 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Start Service"
            android:id="@+id/btn_startService"
            android:layout_margin="5dp"
            android:onClick="onClick"
            />
        
        <Button 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Stop Service"
            android:id="@+id/btn_stopService"
            android:layout_margin="5dp"
            android:onClick="onClick"
            />
        
        <Button 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Bind Service"
            android:id="@+id/btn_bindService"
            android:layout_margin="5dp"
            android:onClick="onClick"
            />
        
        <Button 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Unbind Service"
            android:id="@+id/btn_unbindService"
            android:layout_margin="5dp"
            android:onClick="onClick"
            />
        
        
    </LinearLayout>
    

</FrameLayout>

Service代碼:

public class MyStartService extends Service {
	
	public void onCreate() {
		super.onCreate();
		Log.i("TAG", "MyStartService --> onCreate");
	}
	
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		Log.i("TAG", "MyStartService --> onStart");
	}
	
	//在Android2.0時系統引進了onStartCommand方法取代onStart方法,
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i("TAG", "MyStartService --> onStartCommand");
		return super.onStartCommand(intent, flags, startId);
	}

	//服務在綁定時調用,
	//如果返回值爲null,則不會調用ServiceConnection的onServiceConnected()方法
	public IBinder onBind(Intent intent) {
		Log.i("TAG", "MyStartService --> onBind");
		return new Binder() {
			
		};  
	}
	
	public boolean onUnbind(Intent intent) {
		Log.i("TAG", "MyStartService --> onUnbind");
		return super.onUnbind(intent);
	}
	
	public void onDestroy() {
		super.onDestroy();
		Toast.makeText(this, "service destroy", Toast.LENGTH_SHORT).show();
		Log.i("TAG", "MyStartService --> onDestroy");
	}

}

Service在清單文件中的註冊:

<service android:name="com.sjc.myproject.apis.service.MyStartService"></service>





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章