Android四大組件之—— 使用服務進行后台操作


 

什么是服務

       服務是一個沒有可視化界面的組件,它可以在后台長期運行並進行各種操作。

 

服務的創建

       我們只需要繼承Service類並實現相應的方法即可創建服務

       要想啟動服務,還得在AndroidManifest中注冊服務

 

服務類的示例代碼

 

package com.whathecode.servicedemo;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;

public class ExtendsionService extends Service
{

	/**
	 * 當服務第一次被創建的時候調用此方法
	 */
	@Override
	public void onCreate()
	{
		
		super.onCreate();
		Toast.makeText(getBaseContext(), "服務被創建了", Toast.LENGTH_SHORT).show();
	}
	
	/**
	 * 當通過startService方法啟動服務時此方法被調用
	 */
	@Override
	public int onStartCommand(Intent intent, int flags, int startId)
	{
		Toast.makeText(getBaseContext(), "服務被啟動了", Toast.LENGTH_SHORT).show();
		return super.onStartCommand(intent, flags, startId);
	}

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

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

}

 

使用startService啟動服務

主界面的邏輯代碼:

 

 
        
package com.whathecode.servicedemo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity
{

	Intent service = null;
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//創建服務
		service = new Intent(this, ExtendsionService.class);
	}

	public void start(View view)
	{
		//啟動服務
		startService(service);
	}
	
	public void stop(View view)
	{
		//停止服務
		stopService(service);
	}
}

 

注冊服務:

 

<service android:name="com.whathecode.servicedemo.BackgroundService"></service>

 

運行效果:

 

startService

 

注意:

         當我們第一次點擊啟動服務按鈕的時候,onCreate方法和onStartCommand方法依次執行,

         但在第二次點擊啟動服務按鈕的時候,這個服務已經處於運行狀態,onCreate方法不再執行第二次,

         而onStartCommand方法總是在調用startService啟動服務的時候執行。

         onDestroy方法在stopService方法被調用后執行。

 

除了使用startService方法啟動服務外,我們還可以使用Bind的方式啟動服務。

前者和后者的不同在於:

      服務的生命周期不依賴於啟動者。服務被啟動后一直在后台運行直到調用stopService被停止。

       使用Bind方式啟動服務,服務的生命周期依賴於啟動者。即服務在啟動者退出后自動銷毀。

 

使用Bind方式啟動服務

主要使用bindService方法啟動服務,unbindService方法銷毀服務。

使用此方式啟動服務的好處是,bind定成功的時候服務返回一個IBinder對象,

我們可以通過在服務類里面實現這個對象,從而訪問服務里面的具體方法。

從而達到和服務溝通的目的。

 

注意:

        我們不能以直接實例化服務的方式調用里面的方法。

 

另外:

       如果在退出服務的時候沒有解綁,那么程序就會拋出異常IllegalArgumentException異常。

       因此,每次調用bindService啟動服務,完成后需要退出服務都需要使用unbindService 解綁。  

 

示例代碼:

package com.whathecode.servicedemo;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;

public class MainActivity extends Activity
{

	Intent service = null;
	IReceptionist rpst;

	/**
	 * bindService和unbindService方法使用的參數
	 */
	private ServiceConnection conn = new ServiceConnection()
	{
		
		//此方法在服務連接被意外終止的時候被調用,
		@Override
		public void onServiceDisconnected(ComponentName name)
		{
		
		}
		
		//當服務被連接上的時候自動調用這個方法,第二個參數是服務類onBind方法中返回的對象
		@Override
		public void onServiceConnected(ComponentName name, IBinder service)
		{
			rpst = (IReceptionist) service;
			rpst.callExtendsionNumber();
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//創建服務
		service = new Intent(this, ExtendsionService.class);
	}

	public void start(View view)
	{
		//啟動服務
		startService(service);
	}
	
	public void stop(View view)
	{
		//停止服務
		stopService(service);
	}
	
	public void bind(View view)
	{
		//綁定服務
		bindService(service, conn , BIND_AUTO_CREATE);
	}
	
	public void unBind(View view)
	{
		//解綁服務
		unbindService(conn);
	}
}

 

繼承ServiceBinder對象,並實現自定義接口:

通過這個方式,我們可以暴露只需要的方法,實現代碼的保護。

 

IReceptionist接口代碼:
package com.whathecode.servicedemo;

public interface IReceptionist 
{
	public void callExtendsionNumber();
}

 

ExtendsionService服務類代碼:

 

package com.whathecode.servicedemo;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class ExtendsionService extends Service
{

	private static final String TAG = "ExtendsionService";

	/**
	 * 當服務第一次被創建的時候調用此方法
	 */
	@Override
	public void onCreate()
	{
		
		super.onCreate();
		Toast.makeText(getBaseContext(), "服務被創建了", Toast.LENGTH_SHORT).show();
	}
	
	/**
	 * 當通過startService方法啟動服務時此方法被調用
	 */
	@Override
	public int onStartCommand(Intent intent, int flags, int startId)
	{
		Toast.makeText(getBaseContext(), "服務被啟動了", Toast.LENGTH_SHORT).show();
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public IBinder onBind(Intent intent)
	{
		return new ServiceBinder();
	}

	@Override
	public void onDestroy()
	{
		Toast.makeText(getBaseContext(), "服務被銷毀了", Toast.LENGTH_SHORT).show();
		Log.d(TAG, "服務被銷毀了");
		super.onDestroy();
	}
	
	public void putExtendsion()
	{
		Toast.makeText(getBaseContext(), "正在幫你轉接分機", Toast.LENGTH_SHORT).show();
	}
	
	/**
	 * 
	 * 繼承Binder並實現IReceptionist接口
	 * 繼承Binder類的目的是onBind方法中需要返回這個類型的對象
	 * 
	 * 實現IReceptionist接口是暴露方法的需要
	 */
	private class ServiceBinder extends Binder implements IReceptionist
	{
		public void callExtendsionNumber()
		{
			putExtendsion();
		}
		
		private void otherMethod()
		{
			
		}
	}
}

 

運行效果:

bindService

 

注意看上圖,我們在按下返回鍵的時候,Activity被銷毀,由它啟動的服務也跟着被銷毀。

這樣的服務貌似作用不大,有沒有辦法在退出Activity的時候不退出服務呢?

答案是有的:Android允許我們先啟動一個服務,然后再調用bindService綁定到服務,

                    這樣,我們既可以達到和服務溝通的目的,也可以使服務長期在后台運行。

 

看下圖:

bindService

 

通過下面的圖,就可以更清楚地理解上面代碼的工作原理:

 

Service


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM