• Xamarin.Android开发实践(五)


    一、服务的生命周期

    服务与活动一样,在它的整个生命周期中存在着一些事件,下图可以很好解释整个过程以及涉及到的方法:

    在真实的使用中,Service来还包含一个OnBind方法,并且必须要使用该方法,但是只要返回NULL即可,除非当前服务是一个绑定服务,那么就要返回实现了IBinder的实例。

    二、回调方法的总结

    上图中涉及到了几个方法,下面将做简单的介绍:

    OnCreate:只会在服务第一次开启的时候调用,主要负责一些初始化代码

    OnStartCommand:每次启动服务都会调用该方法,可能来自StartService或者由系统重启。一般负责开启需要长时间的任务。并且该方法还要返回StartCommandResult类型的枚举,该返回值将影响系统重启该服务的细节。

    OnDestroy:当服务使用StopSelf或者StopService时调用,主要用来释放资源等。

    三、返回不同StartCommandResult服务的区别

    Sticky:当服务由于内存不够被系统关闭后,将会由系统重启该服务,但是传入OnStartCommand方法的intent参数为NULL,意味着该类型的服务无法恢复上次的状态,只能进行常规的长时间任务。

    RedeliverIntent:该类型的服务与Sticky的唯一的区别就是在系统重启该服务时,将会将上次关闭的服务的状态传递给OnStartCommand方法,用来恢复上次的任务继续执行。适合需要长时间连续的任务。

    NotSticky:该服务被系统关闭后将不会重启。

    StickyCompatibility:在API 5或以上的环境中的行为与Sticky一样,相反在API 5以下可能不会重启服务。

    四、实现一个服务

    这里我们需要继承自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 } 

    五、启用与停止服务

    有了上面的服务我们现在就可以开启它了,开启服务的方法如下:

    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 } 

     最终在模拟机上进行测试,得出下面的结果:

     从中可以看到多个连续的启动服务,因为笔者按下了返回退出了应用,然后再返回到应用中,开启服务,那么就只显示启动服务了,而不会经过创建服务了。

    六、使用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号,同时在完成执行后,我们再点关闭服务就没有任何反应了,因为服务自己已经把自己关闭了。

    七、通过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但是传递的参数已经变成了字符串。

  • 相关阅读:
    .NET Framework类库大概
    CTS、CLS、CIL与CLR
    .NETFramework、CLR、.NET Framework class library、托管代码是什么
    万维网三大核心技术
    Clang、GCC和LLVM是什么
    常见开源许可证、开源协议GPL、BSD、MIT、Mozilla、Apache和LGPL之间区别
    编译原理之变量、名字与标识符
    编译原理之静态策略与动态策略
    Jupyter Notebook打开任意文件
    修改VsCodes的语言为中文
  • 原文地址:https://www.cnblogs.com/ShaYeBlog/p/4617838.html
Copyright © 2020-2023  润新知