Service和IntentService

IntentService是Service的子类,他不是普通的Service,比普通的Service增加了额外功能。

Service本身存在两个问题:

Service不会专门启动一条单独的线程,Service与它所在的应用处于同一个进程中。

Service也不是一条新的线程,因此不应该在Service中直接处理耗时任务。

如果开发者需要在Service中处理耗时任务,建议在Service中另外启动一条新的线程来处理该耗时任务。直接在其他程序组件中启动子线程来处理耗时任务不行吗?这种方式不可靠,由于Activity会被用户退出,BroadcastReceiver的生命周期本身就很短,可能出现的情况是:在子线程还没有结束的情况下,Activity已经被用户退出了,或者BroadcastReceiver已经结束了。在Activity一经推出,BroadcastReceiver已经结束的情况下,此时他们所处的进程就变成了空进程。系统需要内存的时候,可能就会有优先终止该进程。如果宿主进程被终止,那么该进程内的所有子线程也会被终止,这样就导致线程无法执行该任务。

而IntentService正好可以弥补Service上述两个不足:IntentService将会使用队列来管理请求Intent,每当客户代码通过Intent请求启动IntentService的时候,IntentService会将该Intent加入队列中,然后开启一条新的worker线程来处理该Intent,该线程保证同一时刻只处理一个Intent,由于IntentService使用新的worker线程处理Intent请求,因此,IntentService不会阻塞主线程,所以,IntentService自己就可以处理耗时任务。

IntentService有如下特征:

IntentService会创建单独的worker线程来处理所有的Intent请求。

IntentService会创建单独的worker线程来处理OnHandlerIntent()方法实现代码,因此开发者无需处理多线程问题。

当所有的请求处理完成以后,IntentService会自动停止,因此开发者无需调用stopSelf()方法来停止该Service。

为Service的onbind()方法提供默认实现,默认实现的onBind()返回为null。

为service的OnStartCommand()方法提供了默认实现,该实现会请求Intent添加到队列中。

从上面的介绍可以看出,扩展IntentService实现Service无需重写onBind(),OnStartCommand()方法,只要重写onhandleIntent()方法即可。

下面是两个测试例子:

public class MyService extends Service
{
    public MyService()
    {
    }

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        long endTime = System.currentTimeMillis() + 20 * 1000;
        System.out.println("onStart");
        while (System.currentTimeMillis() < endTime)
        {
            synchronized (this)
            {
                try
                {
                    wait(endTime - System.currentTimeMillis());
                }
                catch (Exception e)
                {
                }
            }
        }
        System.out.println("-----耗时任务执行完成-----");
        return START_STICKY;
    }

public class MyIntentService extends IntentService
{

    public MyIntentService()
    {
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent)
    {
        long endTime = System.currentTimeMillis() + 20*1000;
        System.out.println("onStart");
        while(System.currentTimeMillis() < endTime)
        {
            synchronized (this)
            {
                try
                {
                    wait(endTime - System.currentTimeMillis());
                }
                catch (Exception e)
                {
                }
                System.out.println("-----耗时任务执行完成-----");
            }
        }
    }
}

测试的Activity
public class MainActivity extends Activity
{

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void startService()
    {
        Intent intent = new Intent(this,MyService.class);
        startService(intent);
    }

    public void startIntentService()
    {
        Intent intent = new Intent(this,MyIntentService.class);
        startService(intent);
    }
}
运行该实例,如果启动普通的Service按钮,将会激发StartService()方法,导致UI线程被阻塞,出现ANR异常。如果调用IntentService来启动,虽然也执行耗时任务,但由于MyIntentService会使用单独的worker线程,因此,不会阻塞前台,程序不会失去响应。


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值