不知道大家有没有和我一样,以前做项目或者练习的时候一直都是用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是一个通过Context.startService(Intent)启动可以处理异步请求的Service,使用时你只需要继承IntentService和重写其中的onHandleIntent(Intent)方法接收一个Intent对象,在适当的时候会停止自己(一般在工作完成的时候). 所有的请求的处理都在一个工作线程中完成,它们会交替执行(但不会阻塞主线程的执行),一次只能执行一个请求.

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

1.Service:packagecom.zhf.service;

importAndroid.app.Service;

importAndroid.content.Intent;

importAndroid.os.IBinder;

publicclassMyServiceextendsService {

@Override

publicvoidonCreate() {

super.onCreate();

}

@Override

publicvoidonStart(Intent intent,intstartId) {

super.onStart(intent, startId);

//经测试,Service里面是不能进行耗时的操作的,必须要手动开启一个工作线程来处理耗时操作

System.out.println("onStart");

try{

Thread.sleep(20000);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println("睡眠结束");

}

@Override

publicIBinder onBind(Intent intent) {

returnnull;

}

}

2.IntentService:packagecom.zhf.service;

importAndroid.app.IntentService;

importAndroid.content.Intent;

publicclassMyIntentServiceextendsIntentService {

publicMyIntentService() {

super("yyyyyyyyyyy");

}

@Override

protectedvoidonHandleIntent(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("睡眠结束");

}

}

测试主程序:packagecom.zhf.service;

importAndroid.app.Activity;

importAndroid.content.Intent;

importAndroid.os.Bundle;

publicclassServiceDemoActivityextendsActivity {

/** Called when the activity is first created. */

@Override

publicvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

startService(newIntent(this,MyService.class));//主界面阻塞,最终会出现Application not responding

//连续两次启动IntentService,会发现应用程序不会阻塞,而且最重的是第二次的请求会再第一个请求结束之后运行(这个证实了IntentService采用单独的线程每次只从队列中拿出一个请求进行处理)

startService(newIntent(this,MyIntentService.class));

startService(newIntent(this,MyIntentService.class));

}

}

IntentService类的实现( 精简版 )

package com.ghg.MyIntentService;

import android.app.Service;

import android.content.Intent;

import android.os.Handler;

import android.os.HandlerThread;

import android.os.IBinder;

import android.os.Looper;

import android.os.Message;

/**

* IntentService类的精简版,在(main线程)activity启动下载服务类,把需要下载的资源路径传给service,在service中,

* 创建handler对象和消息对象,工作进程,然后通过handler对象把消息发送到和handler绑定的消息队列中(工作线程中),下载任务,

* 下载结束后,把本次的启动的service关闭;

* @author gaohong

*

*/

public class MyIntentService extends Service {

HandlerThread thread;

Handler handler;

/**

* 初始化工作线程和handler

*/

@Override

public void onCreate() {

// TODO Auto-generated method stub

super.onCreate();

thread=new HandlerThread("workThread");

System.out.println("在"+Thread.currentThread().getName()+"线程中创建工作线程");

thread.start();

Looper looper=thread.getLooper();

handler=new Handler(looper){

@Override

public void handleMessage(Message msg) {

// TODO Auto-generated method stub

System.out.println("在"+Thread.currentThread().getName()+"中处理消息");

onHandleIntent((Intent)msg.obj);

stopSelf(msg.arg1);//下载结束后把该次的调用service结束

}

};

}

protected void onHandleIntent(Intent intent) {

// TODO Auto-generated method stub

String uri=intent.getStringExtra("uri");

try {

thread.sleep(3000);//相当于下载任务;

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

/*

* 创建消息,用handler发送

*

*/

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

// TODO Auto-generated method stub

Message msg=Message.obtain();

msg.obj=intent;

msg.arg1=startId;

System.out.println("在"+Thread.currentThread().getName()+"线程中发送消息");

handler.sendMessage(msg);

return super.onStartCommand(intent, flags, startId);

}

@Override

public void onDestroy() {

// TODO Auto-generated method stub

thread.quit();

super.onDestroy();

}

@Override

public IBinder onBind(Intent intent) {

// TODO Auto-generated method stub

return null;

}

}

activity中的代码:package com.ghg.MyIntentService;

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

public class Day1305_MyIntentServiceActivity extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

Intent intent=new Intent(this, MyIntentService.class);

intent.putExtra("uri", "http://192.168.1.162:8080/musiconline/musics/001.mp3");

startService(intent);

}

}

android服务开启线程,android之service与intentService的不同相关推荐

  1. android服务无法启动,Android服务无法启动(Android service would't start)

    Android服务无法启动(Android service would't start) 我正在尝试在Android中实现简单的服务,但我无法统计基本服务. 这是我的主要课程: import java ...

  2. android服务应用场景,Android Service的使用介绍

    简介 Service是Android应用程序中的一个组件,与用户不进行交互,可以长期的执行在后台.当新建一个服务的时候需要在AndroidManifest.xml文件中进行声明.服务可以通过Conte ...

  3. android服务常驻内存,android service常驻内存的一点思考

    我们总是不想自己的Android service被系统清理,以前时候大家最常用的办法就是在JNI里面fork出子进程,然后监视 service进程状态,被系统杀死了就重启它. 我分别在android4 ...

  4. android服务下载apk,Android 一个简单的版本更新下载apk小示例

    一.简介: 1.运用 okhttp + notification 通知栏带进度的下载apk,下载完毕后并自动安装,如果用户取消可在通知栏点击安装,点击一次通知栏移除,同时支持自动静默下载(后台默默下载 ...

  5. android 服务自动结束,Android服务自动停止

    我正在制作一个带有闹钟功能的应用程序.我正在使用这种服务,不断检查设备的当前时间与我的数据库中的时间.Android服务自动停止 我的问题是,如果应用程序从后台删除或设备是rebooted,此serv ...

  6. android服务无法启动,Android应用程序无法启动服务

    嘿,我正在尝试在我的 Android应用程序上实现一项服务.服务必须执行活动的相同任务. IE,如果在CallLog.Calls内容提供程序上发生某些更改,则必须通知服务并将数据插入数据库,即使应用程 ...

  7. android服务下载apk,android下载apk并安装

    1.设置权限 2.业务代码 package com.example.esri.app04.network; import android.app.ProgressDialog; import andr ...

  8. android 放入主线程,android网络请求不能放在主线程

    网络连接不能放在主线程 android 4.0 以上 网络连接不能放在主线程 4.0 以下 好像可以 在Android4.0以后,会发现,只要是写在主线程(就是Activity)中的HTTP请求,运行 ...

  9. android服务拍视频,Android仿微信拍摄、录制视频,以及视频播放(基于JCameraView和GSYVideoPlayer)...

    本项目使用Androidstudio开发工具 引入权限 引入依赖 //视频录制 implementation 'cjt.library.wheel:camera:1.1.9' //视频播放 api(' ...

最新文章

  1. 千万级智能推荐系统架构演进!
  2. GraphPad Prism软件无响应问题解决办法
  3. python开发web运维工具_Python web 开发工具箱
  4. 七十四、Python | Leetcode数字系列(下篇)
  5. Web前端:11个让你代码整洁的原则
  6. web前端(12)—— 页面布局2
  7. zynq中mgtx应用_Zynq7000系列之芯片引脚功能综述
  8. VUE基础(躺着都能会)
  9. JAVA代码编译流程
  10. 数学建模大赛准备方法及资源分享
  11. c语言课题程序框图,C语言图形五子棋课程设计报告带流程图.docx
  12. CUPS共享打印机服务
  13. NVIDIA GeForce GTX 1050 Ti性能如何
  14. python矩阵内积乘_numpy矩阵向量乘法
  15. HDwiki模板说明
  16. Selenium中的EC模块
  17. Three导入dae格式模型实例
  18. HCNA安全学习笔记
  19. 基于Java毕业设计阳光社区新冠瘦苗接种系统源码+系统+mysql+lw文档+部署软件
  20. python gui是什么_python gui是什么?

热门文章

  1. 我的vim配置---jeffy-vim-v2.3.tar
  2. 检验密码强度的JS类(from thin's blog)
  3. vue中解决three.js出现内存泄漏丢失上下文问题
  4. idea没有错误提示的解决方法(一直处于错误分析中)
  5. MySQL.. ERROR! The server quit without updating PID file问题解决
  6. 【报告分享】2020技术趋势报告-德勤-202003.pdf(附120页pdf原文下载链接)
  7. anaconda显示ImportError: cannot import name ‘secure_write‘
  8. 深度融合 | 当推荐系统遇见知识图谱(三)
  9. 吴恩达深度学习之二《改善深层神经网络:超参数调试、正则化以及优化》学习笔记
  10. 数据结构:B树和B+树的插入、删除图文详解