<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>润物无声 &#187; IntentService</title>
	<atom:link href="http://blog.zhourunsheng.com/tag/intentservice/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.zhourunsheng.com</link>
	<description>天空一朵雨做的云</description>
	<lastBuildDate>Sat, 08 May 2021 05:17:21 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.41</generator>
	<item>
		<title>Android后台服务之IntentService</title>
		<link>http://blog.zhourunsheng.com/2013/09/android%e5%90%8e%e5%8f%b0%e6%9c%8d%e5%8a%a1%e4%b9%8bintentservice/</link>
		<comments>http://blog.zhourunsheng.com/2013/09/android%e5%90%8e%e5%8f%b0%e6%9c%8d%e5%8a%a1%e4%b9%8bintentservice/#comments</comments>
		<pubDate>Sat, 07 Sep 2013 01:07:10 +0000</pubDate>
		<dc:creator><![CDATA[润物无声]]></dc:creator>
				<category><![CDATA[移动开发]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[IntentService]]></category>

		<guid isPermaLink="false">http://blog.zhourunsheng.com/?p=1841</guid>
		<description><![CDATA[<p>在Android的开发过程中，经常需要用到后台服务来完成非UI的工作，比如文件的下载，那么本文提到的Inten [&#8230;]</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2013/09/android%e5%90%8e%e5%8f%b0%e6%9c%8d%e5%8a%a1%e4%b9%8bintentservice/">Android后台服务之IntentService</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></description>
				<content:encoded><![CDATA[<p>在Android的开发过程中，经常需要用到后台服务来完成非UI的工作，比如文件的下载，那么本文提到的IntentService便是一个很好的选择，可以利用它的队列机制，放入一系列的任务，然后系统会依次启动单独的Service来执行任务，免去了自己维护队列的麻烦。</p>
<p>In the new category <b>Read the code</b> I’m going to show the internals of the Android framework. Reading the code of the framework can give you a good impression about what’s going on under the hood. In addition to that knowing how the framework developers solved common problems can help you to find the best solutions when facing problems in your own app code.<span id="more-1841"></span></p>
<p><b>What is the IntentService class good for?</b><br />
This article is about the <a href="https://developer.android.com/reference/android/app/IntentService.html">IntentService</a> class of Android. Extending the IntentService class is the best solution for implementing a background service that is going to process something in a queue-like fashion. You can pass data via <a href="https://developer.android.com/reference/android/content/Intent.html">Intents</a> to the IntentService and it will take care of queuing and processing the Intents on a worker thread one at a time. When writing your IntentService implementation you are required to override the<a href="https://developer.android.com/reference/android/app/IntentService.html#onHandleIntent(android.content.Intent)">onHandleIntent()</a> method to process the data of the supplied Intents.</p>
<p>Let’s take a look at a simple example: This DownloadService class receives Uris to download data from. It will download only one thing at a time with the other requests waiting in a queue.</p>
<table cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td><img style="border: 0px;" alt="" src="http://farm8.staticflickr.com/7393/9690898500_60727af5f0_o.png" width="500" height="360" border="0" /></td>
</tr>
<tr>
<td><a href="https://github.com/pocmo/Android-Zeitgeist-Samples/blob/master/IntentService/DownloadService.java">DownloadService</a></td>
</tr>
</tbody>
</table>
<p><b>The components</b><br />
Before we dip into the source code of the IntentService class, let's first take a look at the different components that we need to know in order to understand the source code.</p>
<p><b>Handler</b> (<a href="https://developer.android.com/reference/android/os/Handler.html">documentation</a>) (<a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/os/Handler.java">source code</a>)<br />
You may already have used Handler objects. When a Handler is created on the UI thread, messages can be posted to it and these messages will be processed on the UI thread.</p>
<p><b>ServiceHandler</b> (<a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/app/IntentService.java#58">source code</a>)<br />
The ServiceHandler inner-class is a helper class extending the Handler class to delegate the Intent wrapped inside a Message object to the IntentService for processing.</p>
<table cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td><img style="border: 0px;" alt="" src="http://farm4.staticflickr.com/3736/9690898370_6ed2c8cdbf_o.png" width="388" height="181" border="0" /></td>
</tr>
<tr>
<td><a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/app/IntentService.java#58">ServiceHandler inner class of android.app.IntentService</a></td>
</tr>
</tbody>
</table>
<p><b>Looper</b> (<a href="https://developer.android.com/reference/android/os/Looper.html">documentation</a>) (<a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/os/Looper.java#Looper">source code</a>)<br />
The Looper class has a MessageQueue object attached to it and blocks the current thread until a Message is received. This message will be passed to the assigned Handler. After that the Looper processes the next message in the queue or blocks again until a message is received.</p>
<p><b>HandlerThread</b> (<a href="https://developer.android.com/reference/android/os/HandlerThread.html">documentation</a>) (<a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/os/HandlerThread.java#HandlerThread">source code</a>)<br />
A HandlerThread is a Thread implementation that does all the Looper setup for you. By creating and starting a HandlerThread instance you will have a running thread with a Looper attached to it waiting for messages to process.</p>
<p><b>Read the code!</b></p>
<p>Now we know enough about all the components to understand the <a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/app/IntentService.java">IntentService code</a>.</p>
<p><b>onCreate()</b></p>
<table cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td><img style="border: 0px;" alt="" src="http://farm8.staticflickr.com/7406/9687656993_78b59cdb59_o.png" width="560" height="150" border="0" /></td>
</tr>
<tr>
<td><a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/app/IntentService.java#101">IntentService.onCreate()</a></td>
</tr>
</tbody>
</table>
<p>At first a HandlerThread is created and started. We now have a background thread running that already has a Looper assigned. This Looper is waiting on the background thread for messages to process.</p>
<p>Next a ServiceHandler is created for this Looper. The Handler’s <a href="https://developer.android.com/reference/android/os/Handler.html#handleMessage(android.os.Message)">handleMessage</a>() method will be called for every message received by the Looper. The ServiceHandler obtains the Intent object from the Message and passes it to the onHandleIntent() method of the IntentService.</p>
<p><b>onStart()</b></p>
<table cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td><img style="border: 0px;" alt="" src="http://farm3.staticflickr.com/2864/9690898434_40462575aa_o.png" width="372" height="120" border="0" /></td>
</tr>
<tr>
<td><a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/app/IntentService.java#115">IntentService.onStart()</a></td>
</tr>
</tbody>
</table>
<p>The onStart() method is called every time <a href="https://developer.android.com/reference/android/content/Context.html#startService(android.content.Intent)">startService()</a> is called. We wrap the Intent in a Message object and post it to the Handler. The Handler will enqueue it in the message queue of the Looper. The onStart() method is deprecated since API level 5 (Android 2.0). Instead onStartCommand() should be implemented.</p>
<p><b>onStartCommand()</b></p>
<table cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td><img style="border: 0px;" alt="" src="http://farm4.staticflickr.com/3833/9687656925_11bee6184c_o.png" width="490" height="90" border="0" /></td>
</tr>
<tr>
<td><a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/app/IntentService.java#129">IntentService.onStartCommand()</a></td>
</tr>
</tbody>
</table>
<p>In onStartCommand() we call onStart() to enqueue the Intent. We return <a href="https://developer.android.com/reference/android/app/Service.html#START_REDELIVER_INTENT">START_REDELIVER_INTENT</a> or<a href="https://developer.android.com/reference/android/app/Service.html#START_NOT_STICKY">START_NOT_STICK</a> depending on what the child class has set via <a href="https://developer.android.com/reference/android/app/IntentService.html#setIntentRedelivery(boolean)">setIntentRedelivery()</a>. Depending on this setting an Intent will be redelivered to the service if the process dies before onHandleIntent() returns or the Intent will die as well.</p>
<p><b>onDestroy()</b></p>
<table cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td><img style="border: 0px;" alt="" src="http://farm4.staticflickr.com/3695/9687656985_3b939dc0f1_o.png" width="200" height="75" border="0" /></td>
</tr>
<tr>
<td><a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/app/IntentService.java#134">IntentService.onDestroy()</a></td>
</tr>
</tbody>
</table>
<p>In onDestroy() we just need to stop the Looper.</p>
<p><b>Conclusion</b></p>
<p>The IntentService code is quite short and simple, yet a powerful pattern. With the <a href="https://developer.android.com/reference/android/os/Handler.html">Handler</a>, <a href="https://developer.android.com/reference/android/os/Looper.html">Looper</a> and <a href="https://developer.android.com/reference/java/lang/Thread.html">Thread</a>class you can easily build your own simple processing queues.</p>
<p>Oh, and if you are looking for an exercise. The code of the onCreate() method contains a TODO comment that I omitted above:</p>
<table cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td><img style="border: 0px;" alt="" src="http://farm4.staticflickr.com/3681/9690898386_5c17f7cefe_o.png" width="550" height="90" border="0" /></td>
</tr>
<tr>
<td><a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/app/IntentService.java#101">TODO in onCreate()</a></td>
</tr>
</tbody>
</table>
<p>引用：<a href="http://www.androidzeitgeist.com/2013/08/read-code-intentservice.html" target="_blank">http://www.androidzeitgeist.com/2013/08/read-code-intentservice.html</a></p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2013/09/android%e5%90%8e%e5%8f%b0%e6%9c%8d%e5%8a%a1%e4%b9%8bintentservice/">Android后台服务之IntentService</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zhourunsheng.com/2013/09/android%e5%90%8e%e5%8f%b0%e6%9c%8d%e5%8a%a1%e4%b9%8bintentservice/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
