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可是传递的参数已经变成了字符串。

相关文章
相关标签/搜索