- 浏览: 2204973 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (1240)
- mac/IOS (287)
- flutter (1)
- J2EE (115)
- android基础知识 (582)
- android中级知识 (55)
- android组件(Widget)开发 (18)
- android 错误 (21)
- javascript (18)
- linux (70)
- 树莓派 (18)
- gwt/gxt (1)
- 工具(IDE)/包(jar) (18)
- web前端 (17)
- java 算法 (8)
- 其它 (5)
- chrome (7)
- 数据库 (8)
- 经济/金融 (0)
- english (2)
- HTML5 (7)
- 网络安全 (14)
- 设计欣赏/设计窗 (8)
- 汇编/C (8)
- 工具类 (4)
- 游戏 (5)
- 开发频道 (5)
- Android OpenGL (1)
- 科学 (4)
- 运维 (0)
- 好东西 (6)
- 美食 (1)
最新评论
-
liangzai_cool:
请教一下,文中,shell、C、Python三种方式控制led ...
树莓派 - MAX7219 -
jiazimo:
...
Kafka源码分析-序列5 -Producer -RecordAccumulator队列分析 -
hp321:
Windows该命令是不是需要安装什么软件才可以?我试过不行( ...
ImageIO读jpg的时候出现javax.imageio.IIOException: Unsupported Image Type -
hp321:
Chenzh_758 写道其实直接用一下代码就可以解决了:JP ...
ImageIO读jpg的时候出现javax.imageio.IIOException: Unsupported Image Type -
huanghonhpeng:
大哥你真强什么都会,研究研究。。。。小弟在这里学到了很多知识。 ...
android 浏览器
IntentService可以做什么:
如果你有一个任务,分成n个子任务,需要它们按照顺序完成。如果需要放到一个服务中完成,那么IntentService就会使最好的选择。
IntentService是什么:
IntentService是一个Service(看起来像废话,但是我第一眼看到这个名字,首先注意的是Intent啊。),所以如果自定义一个IntentService的话,一定要在AndroidManifest.xml里面声明。
从上面的“可以做什么”我们大概可以猜测一下IntentService要有什么特性。
首先要明确的是,如果在Activity中启动一个Service,那么这个Service是在主线程中的。所以在IntentService中需要一个工作线程来完成Intent请求。从IntentService的定义可以印证该猜测:
IntentService用来按要求处理异步请求(以Intent的方式发送的)。客户端通过调用startService(Intent)发送请求,服务会按照要求启动,用自己的工作线程(区别于UI主线程)处理每个Intent(请求),当完成所有的请求之后,自动关闭。
IntentService源码解析:
干货来了!IntentService代码包含了一个工作线程Thread、工作线程的Looper、工作线程的Handler。工作线程用来干活的,Looper用来让线程运转起来的,Handler负责向线程传送工作内容的。IntentService的源码简洁透彻的体现了这一个机制。光是看看这个机制就值了。源码如下:
路径:alps\frameworks\base\core\java\android\app\IntentService.java
从线程分析:
如果是自定义IntentService的话,可以在函数中打印Thread.currentThread().getName()将当前所在线程打印出来。就会发现,只有onHandleIntent的执行是在另外一个新线程中,其他函数(onCreate/onStart/onStartCommand等)的执行都是在main线程(主线程的名称)中。
示例代码:
实际的代码参考如下:
在自定义的Activity的onCreate中添加如下代码:
运行结果如下:
可以看到onHandleIntent是在不同main主线程的工作线程中运行的。
IntentService使用比较简单,但是实现机制比较有趣。感兴趣的同学可以自己把代码敲进去看看。
如果你有一个任务,分成n个子任务,需要它们按照顺序完成。如果需要放到一个服务中完成,那么IntentService就会使最好的选择。
IntentService是什么:
IntentService是一个Service(看起来像废话,但是我第一眼看到这个名字,首先注意的是Intent啊。),所以如果自定义一个IntentService的话,一定要在AndroidManifest.xml里面声明。
从上面的“可以做什么”我们大概可以猜测一下IntentService要有什么特性。
首先要明确的是,如果在Activity中启动一个Service,那么这个Service是在主线程中的。所以在IntentService中需要一个工作线程来完成Intent请求。从IntentService的定义可以印证该猜测:
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(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.
IntentService用来按要求处理异步请求(以Intent的方式发送的)。客户端通过调用startService(Intent)发送请求,服务会按照要求启动,用自己的工作线程(区别于UI主线程)处理每个Intent(请求),当完成所有的请求之后,自动关闭。
IntentService源码解析:
干货来了!IntentService代码包含了一个工作线程Thread、工作线程的Looper、工作线程的Handler。工作线程用来干活的,Looper用来让线程运转起来的,Handler负责向线程传送工作内容的。IntentService的源码简洁透彻的体现了这一个机制。光是看看这个机制就值了。源码如下:
路径:alps\frameworks\base\core\java\android\app\IntentService.java
public abstract class IntentService extends Service { private volatile Looper mServiceLooper; private volatile ServiceHandler mServiceHandler; private String mName; private boolean mRedelivery; private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { //自定义的IntentService子类主要就是实现onHandleIntent这个函数了。注意执行完这个之后就 //stopSelf了,传入的参数是startId。 onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); } } /** * Creates an IntentService. Invoked by your subclass's constructor. * * @param name Used to name the worker thread, important only for debugging. */ public IntentService(String name) { super(); mName = name; } /** * Sets intent redelivery preferences. Usually called from the constructor * with your preferred semantics. * * <p>If enabled is true, * {@link #onStartCommand(Intent, int, int)} will return * {@link Service#START_REDELIVER_INTENT}, so if this process dies before * {@link #onHandleIntent(Intent)} returns, the process will be restarted * and the intent redelivered. If multiple Intents have been sent, only * the most recent one is guaranteed to be redelivered. * * <p>If enabled is false (the default), * {@link #onStartCommand(Intent, int, int)} will return * {@link Service#START_NOT_STICKY}, and if the process dies, the Intent * dies along with it. */ public void setIntentRedelivery(boolean enabled) { mRedelivery = enabled; } @Override public void onCreate() { // TODO: It would be nice to have an option to hold a partial wakelock // during processing, and to have a static startService(Context, Intent) // method that would launch the service & hand off a wakelock. super.onCreate(); //好好看看下面这个代码,启动了一个工作线程,获取线程的Looper,然后用这个Looper初始化Handler句柄 //这样以后可以直接用mHandler.sendMessage的方式将任务直接放到工作线程了。 HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public void onStart(Intent intent, int startId) { //从消息队列中获取一个消息,一般都是用这种方式初始化一个消息,而不是用new message()形式 //效率更高,代码更健壮 Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId;// msg.obj = intent;//这个就是startService的时候传入的Intent了, mServiceHandler.sendMessage(msg);//将包含请求内容Intent的message传入到工作线程中 } /** * You should not override this method for your IntentService. Instead, * override {@link #onHandleIntent}, which the system calls when the IntentService * receives a start request. * @see android.app.Service#onStartCommand */ @Override public int onStartCommand(Intent intent, int flags, int startId) { //注意调用了onStart,和它传入的值。 onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } @Override public void onDestroy() { mServiceLooper.quit(); } /** * Unless you provide binding for your service, you don't need to implement this * method, because the default implementation returns null. * @see android.app.Service#onBind */ @Override public IBinder onBind(Intent intent) { return null; } /** * This method is invoked on the worker thread with a request to process. * Only one Intent is processed at a time, but the processing happens on a * worker thread that runs independently from other application logic. * So, if this code takes a long time, it will hold up other requests to * the same IntentService, but it will not hold up anything else. * When all requests have been handled, the IntentService stops itself, * so you should not call {@link #stopSelf}. * * @param intent The value passed to {@link * android.content.Context#startService(Intent)}. */ protected abstract void onHandleIntent(Intent intent); }
从线程分析:
如果是自定义IntentService的话,可以在函数中打印Thread.currentThread().getName()将当前所在线程打印出来。就会发现,只有onHandleIntent的执行是在另外一个新线程中,其他函数(onCreate/onStart/onStartCommand等)的执行都是在main线程(主线程的名称)中。
示例代码:
实际的代码参考如下:
package com.example.fmdemo; import android.app.IntentService; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class IntentServiceDemo extends IntentService { private static final String TAG = "IntentServiceDemo"; public IntentServiceDemo() { super("IntentServiceDemo"); } public IntentServiceDemo(String name) { super(name); // TODO Auto-generated constructor stub } @Override protected void onHandleIntent(Intent arg0) { // TODO Auto-generated method stub String action = arg0.getExtras().getString("param"); if ("oper1".equals(action)) { Log.i(TAG, "onHandleIntent oper1 threadname = " + Thread.currentThread().getName()); } else if ("oper2".equals(action)) { Log.i(TAG, "onHandleIntent oper2 threadname = " + Thread.currentThread().getName()); } try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub Log.i(TAG, "onBind threadname = " + Thread.currentThread().getName()); return super.onBind(intent); } @Override public void onCreate() { // TODO Auto-generated method stub Log.i(TAG, "onCreate threadname = " + Thread.currentThread().getName()); super.onCreate(); } @Override public void onDestroy() { // TODO Auto-generated method stub Log.i(TAG, "onDestroy threadname = " + Thread.currentThread().getName()); super.onDestroy(); } @Override public void onStart(Intent intent, int startId) { // TODO Auto-generated method stub Log.i(TAG, "onStart threadname = " + Thread.currentThread().getName()); super.onStart(intent, startId); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub Log.i(TAG, "onStartCommand threadname = " + Thread.currentThread().getName()); return super.onStartCommand(intent, flags, startId); } @Override public void setIntentRedelivery(boolean enabled) { // TODO Auto-generated method stub Log.i(TAG, "setIntentRedelivery threadname = " + Thread.currentThread().getName()); super.setIntentRedelivery(enabled); } }
在自定义的Activity的onCreate中添加如下代码:
Intent startServiceIntent = new Intent("com.example.fmdemo.intentservice"); Bundle bundle = new Bundle(); bundle.putString("param", "oper1"); startServiceIntent.putExtras(bundle); startService(startServiceIntent); Intent startServiceIntent2 = new Intent("com.example.fmdemo.intentservice"); Bundle bundle2 = new Bundle(); bundle2.putString("param", "oper2"); startServiceIntent2.putExtras(bundle2); startService(startServiceIntent2);
运行结果如下:
07-01 06:58:23.557: I/IntentServiceDemo(3732): onCreate threadname = main 07-01 06:58:23.571: I/IntentServiceDemo(3732): onStartCommand threadname = main 07-01 06:58:23.571: I/IntentServiceDemo(3732): onStart threadname = main 07-01 06:58:23.576: I/IntentServiceDemo(3732): onHandleIntent oper1 threadname = IntentService[IntentServiceDemo] 07-01 06:58:23.577: I/IntentServiceDemo(3732): onStartCommand threadname = main 07-01 06:58:23.577: I/IntentServiceDemo(3732): onStart threadname = main 07-01 06:58:25.577: I/IntentServiceDemo(3732): onHandleIntent oper2 threadname = IntentService[IntentServiceDemo] 07-01 06:58:27.579: I/IntentServiceDemo(3732): onDestroy threadname = main
可以看到onHandleIntent是在不同main主线程的工作线程中运行的。
IntentService使用比较简单,但是实现机制比较有趣。感兴趣的同学可以自己把代码敲进去看看。
发表评论
-
带你深入理解 FLUTTER 中的字体“冷”知识
2020-08-10 23:40 635本篇将带你深入理解 Flutter 开发过程中关于字体和文 ... -
Flutter -自定义日历组件
2020-03-01 17:56 1111颜色文件和屏幕适配的文件 可以自己给定 import ... -
Dart高级(一)——泛型与Json To Bean
2020-02-23 19:13 1005从 Flutter 发布到现在, 越来越多人开始尝试使用 Da ... -
flutter loading、Progress进度条
2020-02-21 17:03 1181Flutter Progress 1 条形无固定值进度条 ... -
Flutter使用Https加载图片
2020-02-21 01:39 1020Flutter使用Https加载图片 使用http加载图片出 ... -
flutter shared_preferences 异步变同步
2020-02-21 00:55 848前言 引用 在开发原生iOS或Native应用时,一般有判断上 ... -
Flutter TextField边框颜色
2020-02-19 21:31 937监听要销毁 myController.dispose(); T ... -
flutter Future的正确用法
2020-02-18 21:55 808在flutter中经常会用到异步任务,dart中异步任务异步处 ... -
记一次Flutter简单粗暴处理HTTPS证书检验方法
2020-02-18 14:13 979最近在做Flutter项目到了遇到一个无解的事情,当使用Ima ... -
flutter 获取屏幕宽度高度 通知栏高度等屏幕信息
2019-07-27 08:39 1344##MediaQuery MediaQuery.of(con ... -
关于flutter RefreshIndicator扩展listview下拉刷新的问题
2019-07-10 19:40 1143当条目过少时listview某些嵌套情况下可能不会滚动(条目 ... -
flutter listview 改变状态的时候一直无限添加
2019-07-10 16:01 793setstate的时候会一直无限的调用listview.bui ... -
Flutter Android端启动白屏问题的解决
2019-07-09 00:51 1527问题描述 Flutter 应用在 Android 端上启动时 ... -
Flutter中SnackBar使用
2019-07-08 23:43 781底部弹出,然后在指定时间后消失。 注意: build(Bui ... -
Flutter 之点击空白区域收起键盘
2019-07-08 18:43 1792点击空白处取消TextField焦点这个需求是非常简单的,在学 ... -
Flutter 弹窗 Dialog ,AlertDialog,IOS风格
2019-07-08 18:04 1384import 'package:flutter/mate ... -
flutter ---TextField 之 输入类型、长度限制
2019-07-08 14:30 2337TextField想要实现输入类型、长度限制需要先引入impo ... -
【flutter 溢出BUG】键盘上显示bottom overflowed by 104 PIXELS
2019-07-08 11:13 1567一开始直接使用Scaffold布局,body:new Colu ... -
解决Flutter项目卡在Initializing gradle...界面的问题
2019-07-07 12:53 880Flutter最近很火,我抽出了一点时间对Flutter进行了 ... -
关于android O 上 NotificationChannel 的一些注意事项
2019-07-04 11:47 942最近在适配android O,遇到个问题,应用中原本有设置界面 ...
相关推荐
**IntentService详解** 1. **单线程模型**:IntentService内部使用了一个工作队列和一个工作线程,保证同一时间只有一个Intent被处理,避免了多线程并发的问题。 2. **自动停止**:IntentService在`onHandleIntent()...
对于耗时的操作(如大文件复制或删除),源代码可能会使用`AsyncTask`或者`IntentService`进行后台处理,并通过`Notification`向用户反馈进度。 8. **安全与权限处理** 在Android 6.0(Marshmallow)及以上版本,...
这份"Android应用开发详解的源码"提供了丰富的实例和项目代码,为初学者提供了一个宝贵的资源库,帮助他们深入掌握Android开发技能。以下是这个压缩包中可能包含的一些关键知识点: 1. **Activity生命周期**:...
这些只是Android应用开发的部分知识点,通过《Android应用开发详解》的源码学习,你可以深入理解每个概念的实际应用,同时还能看到作者如何解决实际问题,提升自己的编程技巧。在实践中不断探索和学习,才能真正成为...
《Android核心技术与实例详解》随书源码涵盖了多个章节的内容,包括第4章至第18章的部分章节。这些源代码实例旨在帮助读者深入理解Android开发中的关键技术和实践应用。以下是对各章节涉及知识点的详细解释: 第4章...
Android提供了AsyncTask、IntentService、Handler/Looper机制和最近的Retrofit、Volley库来实现异步网络请求。理解这些工具的工作原理和使用场景是至关重要的。 **第6章:缓存策略** 为了提高用户体验和减少服务器...
《Android核心技术与实例详解》是一本深入探讨Android开发的书籍,其提供的完整源码是学习和实践Android开发的重要资源。本书涵盖了Android系统的核心组件、框架以及常见应用开发的实例,旨在帮助开发者掌握Android...
在本资源中,"Android应用开发详解教材源码(下册)--实例源码" 提供了8个单元共计30多个实例的源代码,旨在帮助开发者深入理解Android应用程序的开发过程。这些实例覆盖了Android开发中的核心概念、组件以及最佳...
【安卓应用开发源码详解】 在安卓应用开发领域,源码是学习和理解应用程序工作原理的关键。这份"安卓应用开发源码"包含了开发者在实际项目中的实践经验,是深入学习安卓编程的重要资源。通过分析和研究这些源码,你...
《Android核心技术与实例详解》是一本深度探讨Android开发的书籍,其项目源码"KDWB_Android"提供了实际操作的示例,对于Android开发者来说,是深入理解Android系统和提升编程技能的重要资源。这个源码主要围绕...
《Android核心技术与实例详解》是Android开发者们常常参考的一本技术书籍,其源码的完整版为学习者提供了深入理解Android开发的宝贵资源。这本书涵盖了Android应用开发的多个重要方面,包括但不限于UI设计、数据存储...
【Android音乐播放器源码详解】 在Android平台上开发一款音乐播放器是一项常见的任务,而能够获得一份详尽注释的源码无疑是学习和提升的好材料。这个“Android音乐播放器源码”提供了一个完整的实现,从用户界面...
此压缩包"Android应用开发详解_源码.rar"可能包含了一系列的示例代码和讲解,旨在帮助初学者或有经验的开发者深入理解Android应用的工作原理。 1. **Android SDK**:Android软件开发工具包(SDK)是开发Android应用...
《Android动漫阅读器源码详解》 Android动漫阅读器源码是专为移动设备设计的一款应用程序,用于在Android平台上浏览和阅读漫画。这份源码提供了一个深入理解Android应用开发,特别是针对多媒体内容展示的绝佳实例。...
源码可能包含使用AsyncTask、IntentService、Loader或现代的协程库(如Kotlin的Coroutines)进行后台操作的实例。此外,可能有关于内存管理、耗电优化和UI流畅性的代码片段。 七、权限管理 随着Android系统的更新,...
《Android应用源码详解——基于饭否客户端》 在Android开发领域,研究开源项目源码是提升技术能力的重要途径之一。本次我们关注的是"饭否客户端"的最新源码资源,这是一份针对Android平台的社交应用源码,旨在帮助...
【Android博客阅读器源码详解】 Android博客阅读器是一款基于Android平台的应用程序,它允许用户浏览和阅读来自不同博客站点的最新文章。源码的分析将深入探讨Android开发中的核心概念和技术,包括网络请求、数据...
《Android 电影购票源码详解》 Android 电影购票源码是一个典型的移动应用开发实例,主要涉及Android平台上的用户界面设计、网络通信、数据处理等多个关键知识点。此源码不仅适用于学习Android应用开发,同时也为...
本资料"Android核心技术与实例详解源码"提供了丰富的代码示例,旨在帮助开发者深入理解Android系统的运作机制,并能将其运用到实际项目中去。以下是根据标题和描述,以及文件名称列表中的"第17章、第18章"所涉及的...