Xamarin.Android開發實踐(五)

原文:Xamarin.Android開發實踐(五)html

1、服務的生命週期

服務與活動同樣,在它的整個生命週期中存在着一些事件,下圖能夠很好解釋整個過程以及涉及到的方法:android

在真實的使用中,Service來還包含一個OnBind方法,而且必需要使用該方法,可是隻要返回NULL便可,除非當前服務是一個綁定服務,那麼就要返回實現了IBinder的實例。ide

 

2、回調方法的總結

上圖中涉及到了幾個方法,下面將作簡單的介紹:post

OnCreate:只會在服務第一次開啓的時候調用,主要負責一些初始化代碼測試

OnStartCommand:每次啓動服務都會調用該方法,可能來自StartService或者由系統重啓。通常負責開啓須要長時間的任務。而且該方法還要返回StartCommandResult類型的枚舉,該返回值將影響系統重啓該服務的細節。this

OnDestroy:當服務使用StopSelf或者StopService時調用,主要用來釋放資源等。url

 

3、返回不一樣StartCommandResult服務的區別

Sticky:當服務因爲內存不夠被系統關閉後,將會由系統重啓該服務,可是傳入OnStartCommand方法的intent參數爲NULL,意味着該類型的服務沒法恢復上次的狀態,只能進行常規的長時間任務。spa

RedeliverIntent:該類型的服務與Sticky的惟一的區別就是在系統重啓該服務時,將會將上次關閉的服務的狀態傳遞給OnStartCommand方法,用來恢復上次的任務繼續執行。適合須要長時間連續的任務。線程

NotSticky:該服務被系統關閉後將不會重啓。3d

StickyCompatibility:在API 5或以上的環境中的行爲與Sticky同樣,相反在API 5如下可能不會重啓服務。

 

4、實現一個服務

這裏咱們須要繼承自Service並還要須要加上Service註解屬性(項目自行新建

1 namespace ServiceStudy 2 { 3  [Service] 4 public class MainService : Service 5  { 6 7  } 8 }

其中[Service]負責在AndroidManifest.xml註冊服務,好比上面的服務將會生成以下字符串:

1 <service android:name="ServiceStudy.MainService"></service>

下面咱們開始具體實現一個服務,上面已經說明了不管任何服務都要重寫OnBind方法,因此咱們先重寫該方法:

1         public override Android.OS.IBinder OnBind(Android.Content.Intent intent) 2  { 3 return null; 4 }

而後是OnCreate方法:

1         public override void OnCreate() 2  { 3 base.OnCreate(); 4 Log.Debug("xamarin", "建立服務"); 5 }

接着是OnStartCommand方法:

1         public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId) 2  { 3 Log.Debug("xamarin", "啓動服務"); 4 return StartCommandResult.Sticky; 5 } 

最後就是OnDestroy方法:

1         public override void OnDestroy() 2  { 3 base.OnDestroy(); 4 Log.Debug("xamarin", "關閉服務"); 5 }

這樣一個簡單的服務就完成了,下面是總體代碼:

 1  [Service]  2 public class MainService : Service  3  {  4 public override void OnCreate()  5  {  6 base.OnCreate();  7 Log.Debug("xamarin", "建立服務");  8  }  9 10 public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId) 11  { 12 Log.Debug("xamarin", "啓動服務"); 13 return StartCommandResult.Sticky; 14  } 15 16 public override void OnDestroy() 17  { 18 base.OnDestroy(); 19 Log.Debug("xamarin", "關閉服務"); 20  } 21 22 public override Android.OS.IBinder OnBind(Android.Content.Intent intent) 23  { 24 return null; 25  } 26 } 

 

 

5、啓用與中止服務

有了上面的服務咱們如今就能夠開啓它了,開啓服務的方法以下:

1 StartService(new Intent(this, typeof(MainService)));

中止服務的方法以下:

1 StopService(new Intent(this, typeof(MainService)));

首先打開Main.axml,再拖拽一個按鈕進去,並設置他們的Text,以及id爲@+id/startButton@+id/stopButton,結果以下:

 接着打開MainActivity.cs文件,爲這兩個按鈕綁定監聽事件:

 1     public class MainActivity : Activity  2  {  3 protected override void OnCreate(Bundle bundle)  4  {  5 base.OnCreate(bundle);  6  SetContentView(Resource.Layout.Main);  7 Button startButton = FindViewById<Button>(Resource.Id.startButton);  8 Button stopButton = FindViewById<Button>(Resource.Id.stopButton);  9 10 startButton.Click += delegate 11  { 12 StartService(new Intent(this, typeof(MainService))); 13  }; 14 15 stopButton.Click += delegate 16  { 17 StopService(new Intent(this, typeof(MainService))); 18  }; 19  } 20 } 

 

 最終在模擬機上進行測試,得出下面的結果:

 從中能夠看到多個連續的啓動服務,由於筆者按下了返回退出了應用,而後再返回到應用中,開啓服務,那麼就只顯示啓動服務了,而不會通過建立服務了。

 

6、使用startId關閉服務

經過上面的例子,你們必定有人不停的開啓服務。固然每次開啓的都是一個新的服務。可是關閉服務的時候並非關閉其中一個,而是把全部的服務都關閉了。由這個就須要考慮一種狀況,就是如何區分不一樣的實例以及關閉不一樣的實例呢?

 

你們能夠看看

 服務中已經提供了專門的方法,固然若是是關閉當前的服務能夠直接用StopSelf(),下面咱們將OnStartCommand中重寫,開啓一個線程:

 1         public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId)  2  {  3 Log.Debug("xamarin", "啓動服務");  4 new Thread(() =>  5  {  6 Log.Debug("xamarin", startId + "號服務的線程啓動");  7 Thread.Sleep(1000);  8 Log.Debug("xamarin", startId + "號服務的線程關閉");  9  StopSelf(startId); 10  }).Start(); 11 return StartCommandResult.Sticky; 12 } 

咱們這裏使用了StopSelft的重載版本關閉了服務。

 

而後咱們再開始進行調試,首先咱們按下一次開啓服務,將出現以下的結果:

 

接着咱們快速的點擊兩次開啓服務,將出現以下的結果:

 

經過這張圖咱們能夠看到,輸出了1號和2號,同時在完成執行後,咱們再點關閉服務就沒有任何反應了,由於服務本身已經把本身關閉了。

 

7、經過Intent Filter開啓服務

上面全部的服務開啓方法都是經過類型開啓的,可是這樣的缺點顯而易見,若是咱們改變了服務的名稱就須要改正其餘的地方,而經過這節咱們將可使用字符串名稱來開啓服務。

這裏咱們須要使用IntentFilter註解屬性,好比下面這樣的註解屬性:

則會在AndroidManifest.xml中生成以下的字符串:

1 <service android:name="ServiceStudy. MainService"> 2 <intent-filter> 3 <action android:name="xamarin-cn.com.mainservice" /> 4 </intent-filter> 5 </service>

咱們先給MainService加上Intent Filter

1  [Service] 2 [IntentFilter(new string[]{"xamarin-cn.com.mainservice"})] 3 public class MainService : Service

而後修改開啓服務地方的代碼:

 1         protected override void OnCreate(Bundle bundle)  2  {  3 base.OnCreate(bundle);  4  SetContentView(Resource.Layout.Main);  5 Button startButton = FindViewById<Button>(Resource.Id.startButton);  6 Button stopButton = FindViewById<Button>(Resource.Id.stopButton);  7  8 startButton.Click += delegate  9  { 10 StartService(new Intent("xamarin-cn.com.mainservice")); 11  }; 12 13 stopButton.Click += delegate 14  { 15 StopService(new Intent("xamarin-cn.com.mainservice")); 16  }; 17 } 

 

這裏咱們依然仍是使用Intent可是傳遞的參數已經變成了字符串。

相關文章
相關標籤/搜索