Android之Service与IntentService的比较

本文对比了Service和IntentService在处理后台耗时任务时的区别。详细介绍了IntentService如何通过队列方式处理Intent请求,并在单独线程中执行,避免阻塞主线程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

耗时的工作在应该放在单独的线程中做,避免用户界面阻塞。例如:文件I/O,网络访问。service在后台运行,不是一个独立的进程,也不是一个独立的线程。它存在于应用程序进程的主线程中。如果需要service做一些例如处理网络连接等耗时操作,应该放到一个单独线程中。所以启动服务,中止进程,服务会停止。启动服务,不用多线程,界面将会阻塞。
一旦启动,即使启动它的对象销毁了,仍然在运行。
只启动,不返回值。

不知道大家有没有和我一样,以前做项目或者练习的时候一直都是用Service来处理后台耗时操作,却很少注意到还有个IntentService,前段时间准备面试的时候看到了一篇关于IntentService的解释,发现了它相对于Service来说有很多更加方便之处,今天在这里稍微来总结下我的心得。

    首先IntentService是继承自Service的,那我们先看看Service的官方介绍,这里列出两点比较重要的地方:

      1.A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.

      2.A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).

      稍微翻一下(英文水平一般大笑)

      1.Service不是一个单独的进程 ,它和应用程序在同一个进程中。

      2.Service不是一个线程,所以我们应该避免在Service里面进行耗时的操作

关于第二点我想说下,不知道很多网上的文章都把耗时的操作直接放在Service的onStart方法中,而且没有强调这样会出现Application Not Responding!希望我的文章能帮大家认清这个误区(Service不是一个线程,不能直接处理耗时的操作)。

       有人肯定会问,那么为什么我不直接用Thread而要用Service呢?关于这个,大家可以网上搜搜,这里不过多解释。有一点需要强调,如果有耗时操作在Service里,就必须开启一个单独的线程来处理!!!这点一定要铭记在心。 

       IntentService相对于Service来说,有几个非常有用的优点,首先我们看看官方文档的说明:

         IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests throughstartService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.

         This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.

         All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.

            稍微翻译理一理,这里主要是说IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程,这里就给我们提供了一个思路,如果有耗时的操作与其在Service里面开启新线程还不如使用IntentService来处理耗时操作。下面给一个小例子:

       1.Service:

  1. package com.zhf.service; 
  2.  
  3. import android.app.Service; 
  4. import android.content.Intent; 
  5. import android.os.IBinder; 
  6.  
  7. public class MyServiceextends Service { 
  8.  
  9.     @Override 
  10.     public void onCreate() { 
  11.         super.onCreate(); 
  12.     } 
  13.      
  14.     @Override 
  15.     public void onStart(Intent intent,int startId) { 
  16.         super.onStart(intent, startId); 
  17.         //经测试,Service里面是不能进行耗时的操作的,必须要手动开启一个工作线程来处理耗时操作 
  18.         System.out.println("onStart"); 
  19.         try
  20.             Thread.sleep(20000); 
  21.         } catch (InterruptedException e) { 
  22.             e.printStackTrace(); 
  23.         } 
  24.         System.out.println("睡眠结束"); 
  25.     } 
  26.      
  27.     @Override 
  28.     public IBinder onBind(Intent intent) { 
  29.         return null
  30.     } 
package com.zhf.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyService extends Service {

	@Override
	public void onCreate() {
		super.onCreate();
	}
	
	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		//经测试,Service里面是不能进行耗时的操作的,必须要手动开启一个工作线程来处理耗时操作
		System.out.println("onStart");
		try {
			Thread.sleep(20000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("睡眠结束");
	}
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
}
           2.IntentService:

  1. package com.zhf.service; 
  2.  
  3. import android.app.IntentService; 
  4. import android.content.Intent; 
  5.  
  6. public class MyIntentServiceextends IntentService { 
  7.  
  8.     public MyIntentService() { 
  9.         super("yyyyyyyyyyy"); 
  10.     } 
  11.  
  12.     @Override 
  13.     protected void onHandleIntent(Intent intent) { 
  14.         // 经测试,IntentService里面是可以进行耗时的操作的 
  15.         //IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent 
  16.         //对于异步的startService请求,IntentService会处理完成一个之后再处理第二个 
  17.         System.out.println("onStart"); 
  18.         try
  19.             Thread.sleep(20000); 
  20.         } catch (InterruptedException e) { 
  21.             e.printStackTrace(); 
  22.         } 
  23.         System.out.println("睡眠结束"); 
  24.     } 
package com.zhf.service;

import android.app.IntentService;
import android.content.Intent;

public class MyIntentService extends IntentService {

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

	@Override
	protected void onHandleIntent(Intent intent) {
		// 经测试,IntentService里面是可以进行耗时的操作的
		//IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent
		//对于异步的startService请求,IntentService会处理完成一个之后再处理第二个
		System.out.println("onStart");
		try {
			Thread.sleep(20000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("睡眠结束");
	}
}

测试主程序:

  1. package com.zhf.service; 
  2.  
  3. import android.app.Activity; 
  4. import android.content.Intent; 
  5. import android.os.Bundle; 
  6.  
  7. public class ServiceDemoActivityextends Activity { 
  8.     /** Called when the activity is first created. */ 
  9.     @Override 
  10.     public void onCreate(Bundle savedInstanceState) { 
  11.         super.onCreate(savedInstanceState); 
  12.         setContentView(R.layout.main); 
  13.         startService(new Intent(this,MyService.class));//主界面阻塞,最终会出现Application not responding 
  14.         //连续两次启动IntentService,会发现应用程序不会阻塞,而且最重的是第二次的请求会再第一个请求结束之后运行(这个证实了IntentService采用单独的线程每次只从队列中拿出一个请求进行处理) 
  15.         startService(new Intent(this,MyIntentService.class)); 
  16.         startService(new Intent(this,MyIntentService.class)); 
  17.     } 
内容概要:本文介绍了多种开发者工具及其对开发效率的提升作用。首先,介绍了两款集成开发环境(IDE):IntelliJ IDEA 以其智能代码补全、强大的调试工具和项目管理功能适用于Java开发者;VS Code 则凭借轻量级和多种编程语言的插件支持成为前端开发者的常用工具。其次,提到了基于 GPT-4 的智能代码生成工具 Cursor,它通过对话式编程显著提高了开发效率。接着,阐述了版本控制系统 Git 的重要性,包括记录代码修改、分支管理和协作功能。然后,介绍了 Postman 作为 API 全生命周期管理工具,可创建、测试和文档化 API,缩短前后端联调时间。再者,提到 SonarQube 这款代码质量管理工具,能自动扫描代码并检测潜在的质量问题。还介绍了 Docker 容器化工具,通过定义应用的运行环境和依赖,确保环境一致性。最后,提及了线上诊断工具 Arthas 和性能调优工具 JProfiler,分别用于生产环境排障和性能优化。 适合人群:所有希望提高开发效率的程序员,尤其是有一定开发经验的软件工程师和技术团队。 使用场景及目标:①选择合适的 IDE 提升编码速度和代码质量;②利用 AI 编程助手加快开发进程;③通过 Git 实现高效的版本控制和团队协作;④使用 Postman 管理 API 的全生命周期;⑤借助 SonarQube 提高代码质量;⑥采用 Docker 实现环境一致性;⑦运用 Arthas 和 JProfiler 进行线上诊断和性能调优。 阅读建议:根据个人或团队的需求选择适合的工具,深入理解每种工具的功能特点,并在实际开发中不断实践和优化。
内容概要:本文围绕低轨(LEO)卫星通信系统的星间切换策略展开研究,针对现有研究忽略终端运动影响导致切换失败率高的问题,提出了两种改进策略。第一种是基于预测的多属性无偏好切换策略,通过预测终端位置建立切换有向图,并利用NPGA算法综合服务时长、通信仰角和空闲信道数优化切换路径。第二种是多业务切换策略,根据不同业务需求使用层次分析法设置属性权重,并采用遗传算法筛选切换路径,同时引入多业务切换管理方法保障实时业务。仿真结果显示,这两种策略能有效降低切换失败率和新呼叫阻塞率,均衡卫星负载。 适合人群:从事卫星通信系统研究的科研人员、通信工程领域的研究生及工程师。 使用场景及目标:①研究和优化低轨卫星通信系统中的星间切换策略;②提高卫星通信系统的可靠性和效率;③保障不同类型业务的服务质量(QoS),特别是实时业务的需求。 其他说明:文章不仅详细介绍了两种策略的具体实现方法,还提供了Python代码示例,包括终端位置预测、有向图构建、多目标优化算法以及业务感知的资源分配等关键环节。此外,还设计了完整的仿真测试框架,用于验证所提策略的有效性,并提供了自动化验证脚本和创新点技术验证方案。部署建议方面,推荐使用Docker容器化仿真环境、Redis缓存卫星位置数据、GPU加速遗传算法运算等措施,以提升系统的实时性和计算效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值