【Android】16.4 IntentService类

分类:C#、Android、VS2015;

创建日期:2016-03-01

一、简介

为了进一步简化Intent过滤器的用法,Android系统又提供了一个IntentService类,这样一来,你也不需要重写其他的方法了,直接实现一个继承自IntentService的类,然后重写OnHandleIntent方法即可。

IntentService类继承自Service类。这个类自动使用工作线程处理所有Service的启动请求(即:对IntentService的每次请求都会自动启动一个线程去处理它)。

因为大多数started服务都不需要“并发”处理多个请求(这实际上是一个危险的多线程情况),所以最佳方式也许就是用IntentService类来实现你的服务。

总之,只要Started Service不需要“并发”处理多个请求,首选的办法就是用IntentService来实现。

1、IntentService的工作机制

IntentService将自动执行以下步骤:

创建一个缺省的工作(worker)线程,它独立于应用程序主线程来执行所有发送到OnStartCommand方法的intent。

创建一个工作队列,每次向你的OnHandleIntent()传入一个intent,这样你就永远不必担心多线程问题了。

在处理完所有的启动请求后,终止服务,因此你就永远不需调用StopSelf方法了。

提供缺省的OnBind()实现代码,它返回null。

提供缺省的OnStartCommand()实现代码,它把intent送入工作队列,稍后会再传给你的OnHandleIntent()实现代码。

以上所有步骤将汇成一个结果:你要做的全部工作就是实现OnHandleIntent()完成客户端提交的任务。(当然你还需要为服务提供一小段构造方法。)

2、实现OnHandleIntent方法

实现IntentService请求的代码很简单,你要做的工作就是在自定义的继承自IntentService类中重写OnHandleIntent()方法即可,它会自动接收每个启动请求的intent,然后自动在后台完成Intent请求的工作。

下面的代码演示了如何重写OnHandleIntent()方法:

[Service]
[IntentFilter(new string[]{"com.xamarin.DemoIntentService"})]
public class DemoIntentService: IntentService
{
    public DemoIntentService () : base("DemoIntentService")
    {
    }

    protected override void OnHandleIntent (Android.Content.Intent intent)
    {
         Console.WriteLine ("perform some long running work");
         Console.WriteLine ("work complete");
    }
}

继承自IntentService的类与继承自Service的自定义类的区别是:继承自IntentService的类需要通过构造函数传递给基类一个字符串,该字符串的作用是标识内部工作线程。

从内部实现代码上来看,IntentService实际上就是把每个Intent发送的请求都放到一个工作队列中,然后分别在不同的线程中处理工作队列中的每个请求,由于这些Intent都是在与主线程不同的单独线程中运行的,当然不会阻止主线程的运行。

当某个Intent处理完后,IntentService会立即自动调用StopSelf方法停止这个Intent。

总之,利用IntentService,我们既不需要在服务中去显式创建单独的线程,也不需要在重写的Ondestroy方法中终止自己创建的线程,这一些都由IntentService类去自动实现,你只需要关注在服务中实现的功能就行了。

二、示例3--IndentServiceDemo

运行截图

image   image

主要设计步骤

(1)添加ch1603_Main.axml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Button
        android:id="@+id/ch1603StartService"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="启动服务" />
    <Button
        android:id="@+id/ch1603StopService"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="停止服务" />
</LinearLayout>

(2)添加ch1603ServiceDemo.cs

using System;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;
using System.Threading;

namespace MyDemos.SrcDemos
{
    [Service]
    [IntentFilter(new string[] { action })]
    public class ch1603ServiceDemo : IntentService
    {
        public const string action = "MyDemos.ch1603Service";

        public ch1603ServiceDemo() : base("ch1603ServiceDemo")
        {
        }

        protected override void OnHandleIntent(Intent intent)
        {
            var myHandler = new Handler(MainLooper);
            myHandler.Post(() =>
            {
                Toast.MakeText(this, "服务已启动", ToastLength.Short).Show();
            });
            for (int i = 1; i <= 10; i++)
            {
                var msg = string.Format("这是来自服务的第{0}个消息", i);
                Thread.Sleep(TimeSpan.FromSeconds(4));
                myHandler.Post(() =>
                {
                    Toast.MakeText(this, msg, ToastLength.Short).Show();
                });
            }
        }

        public override void OnDestroy()
        {
            base.OnDestroy();
            new Handler(MainLooper).Post(() =>
            {
                Toast.MakeText(this, "服务已停止", ToastLength.Short).Show();
            });
        }
    }
}

(3)添加ch1603MainActivity.cs

using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;

namespace MyDemos.SrcDemos
{
    [Activity(Label = "ch1603MainActivity")]
    public class ch1603MainActivity : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.ch1603_Main);
            var start = FindViewById<Button>(Resource.Id.ch1603StartService);
            start.Click += delegate
            {
                StartService(new Intent(ch1603ServiceDemo.action));
            };

            var stop = FindViewById<Button>(Resource.Id.ch1603StopService);
            stop.Click += delegate
            {
                StopService(new Intent(ch1603ServiceDemo.action));
            };
        }
    }
}
原文地址:https://www.cnblogs.com/rainmj/p/5229570.html