{"id":4945,"date":"2024-10-05T11:01:01","date_gmt":"2024-10-05T03:01:01","guid":{"rendered":""},"modified":"2024-10-05T11:01:01","modified_gmt":"2024-10-05T03:01:01","slug":"android taskaffinity_Android\u670d\u52a1\u76d1\u89c6\u624b\u673a","status":"publish","type":"post","link":"https:\/\/mushiming.com\/4945.html","title":{"rendered":"android taskaffinity_Android\u670d\u52a1\u76d1\u89c6\u624b\u673a"},"content":{"rendered":"<div style=\"font-size:16px;\">\n<p>Android&nbsp;\u591a\u7ebf\u7a0b\u8f85\u52a9\u7c7b<\/p>\n<p>\u8f85\u52a9\u7c7b\u533a\u5206\u4e8e\u57fa\u7840\u7c7b<\/p>\n<p>\u57fa\u7840\u7c7b\u5305\u62ecjava\u672c\u6765\u7684\u591a\u7ebf\u7a0b\u7c7b\u3001android\u7684handle\u3001looper\u7b49\u3002<\/p>\n<p>\u8f85\u52a9\u7c7b\u63d0\u4f9b\u4e86\u66f4\u65b9\u4fbf\u7684\u65b9\u6cd5\u3002<\/p>\n<p>1.AsyncTask<\/p>\n<p>\u4e2a\u4eba\u611f\u89c9AsyncTask\u6709\u5f88\u591a\u9650\u5236\uff0c\u4e0d\u662f\u5f88\u65b9\u4fbf\uff0c\u4e0d\u8981\u6ee5\u7528\u3002<\/p>\n<p>Class&nbsp;Overview<\/p>\n<p>AsyncTask&nbsp;enables&nbsp;proper&nbsp;and&nbsp;easy&nbsp;use&nbsp;of&nbsp;the&nbsp;UI&nbsp;thread.&nbsp;This&nbsp;class&nbsp;allows&nbsp;to&nbsp;perform&nbsp;background&nbsp;operations&nbsp;and&nbsp;publish&nbsp;results&nbsp;on&nbsp;the&nbsp;UI&nbsp;thread&nbsp;without&nbsp;having&nbsp;to&nbsp;manipulate&nbsp;threads&nbsp;and\/or&nbsp;handlers.<\/p>\n<p>AsyncTask&nbsp;is&nbsp;designed&nbsp;to&nbsp;be&nbsp;a&nbsp;helper&nbsp;class&nbsp;around&nbsp;Thread&nbsp;and&nbsp;Handler&nbsp;and&nbsp;does&nbsp;not&nbsp;constitute&nbsp;a&nbsp;generic&nbsp;threading&nbsp;framework.&nbsp;AsyncTasks&nbsp;should&nbsp;ideally&nbsp;be&nbsp;used&nbsp;for&nbsp;short&nbsp;operations&nbsp;(a&nbsp;few&nbsp;seconds&nbsp;at&nbsp;the&nbsp;most.)&nbsp;If&nbsp;you&nbsp;need&nbsp;to&nbsp;keep&nbsp;threads&nbsp;running&nbsp;for&nbsp;long&nbsp;periods&nbsp;of&nbsp;time,&nbsp;it&nbsp;is&nbsp;highly&nbsp;recommended&nbsp;you&nbsp;use&nbsp;the&nbsp;various&nbsp;APIs&nbsp;provided&nbsp;by&nbsp;the&nbsp;java.util.concurrent&nbsp;package&nbsp;such&nbsp;as&nbsp;Executor,&nbsp;ThreadPoolExecutor&nbsp;and&nbsp;FutureTask.<\/p>\n<p>An&nbsp;asynchronous&nbsp;task&nbsp;is&nbsp;defined&nbsp;by&nbsp;a&nbsp;computation&nbsp;that&nbsp;runs&nbsp;on&nbsp;a&nbsp;background&nbsp;thread&nbsp;and&nbsp;whose&nbsp;result&nbsp;is&nbsp;published&nbsp;on&nbsp;the&nbsp;UI&nbsp;thread.&nbsp;An&nbsp;asynchronous&nbsp;task&nbsp;is&nbsp;defined&nbsp;by&nbsp;3&nbsp;generic&nbsp;types,&nbsp;called&nbsp;Params,&nbsp;Progress&nbsp;and&nbsp;Result,&nbsp;and&nbsp;4&nbsp;steps,&nbsp;called&nbsp;onPreExecute,&nbsp;doInBackground,&nbsp;onProgressUpdate&nbsp;and&nbsp;onPostExecute.<\/p>\n<p>\u603b\u7ed3\uff1a<\/p>\n<p>1.AsyncTask\u7684\u5b58\u5728\u662f\u4e3a\u4e86\u8ba9\u5f00\u53d1\u8005\u6b63\u786e\u5730\u3001\u65b9\u4fbf\u5730\u4f7f\u7528UI\u7ebf\u7a0b\u3002<\/p>\n<p>2.AsyncTask\u7684\u6267\u884c\u65f6\u95f4\u6700\u591a\u51e0\u79d2\u3002\u518d\u957f\u7684\u4efb\u52a1\u4e0d\u8981\u4f7f\u7528AyncTask\u3002<\/p>\n<p>Developer&nbsp;Guides<\/p>\n<p>For&nbsp;more&nbsp;information&nbsp;about&nbsp;using&nbsp;tasks&nbsp;and&nbsp;threads,&nbsp;read&nbsp;the&nbsp;Processes&nbsp;and&nbsp;Threads&nbsp;developer&nbsp;guide.<\/p>\n<p>Usage<\/p>\n<p>AsyncTask&nbsp;must&nbsp;be&nbsp;subclassed&nbsp;to&nbsp;be&nbsp;used.&nbsp;The&nbsp;subclass&nbsp;will&nbsp;override&nbsp;at&nbsp;least&nbsp;one&nbsp;method&nbsp;(doInBackground(Params...)),&nbsp;and&nbsp;most&nbsp;often&nbsp;will&nbsp;override&nbsp;a&nbsp;second&nbsp;one&nbsp;(onPostExecute(Result).)<\/p>\n<p>AsyncTask\u662f\u62bd\u8c61\u7c7b\u3002<\/p>\n<p>\u81f3\u5c11\u8981\u91cd\u5199doInBackground(...).<\/p>\n<p>\u901a\u5e38\u4e5f\u4f1a\u91cd\u5199&nbsp;onPostExecute(...)<\/p>\n<p>private&nbsp;class&nbsp;DownloadFilesTask&nbsp;extends&nbsp;AsyncTask&nbsp;{<br \/>\n  <!-- --><\/p>\n<p>protected&nbsp;Long&nbsp;doInBackground(URL...&nbsp;urls)&nbsp;{<br \/>\n  <!-- --><\/p>\n<p>int&nbsp;count&nbsp;=&nbsp;urls.length;<\/p>\n<p>long&nbsp;totalSize&nbsp;=&nbsp;0;<\/p>\n<p>for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<\/p>\n<p>totalSize&nbsp;+=&nbsp;Downloader.downloadFile(urls[i]);<\/p>\n<p>publishProgress((int)&nbsp;((i&nbsp;\/&nbsp;(float)&nbsp;count)&nbsp;*&nbsp;100));<\/p>\n<p>\/\/&nbsp;Escape&nbsp;early&nbsp;if&nbsp;cancel()&nbsp;is&nbsp;called<\/p>\n<p>if&nbsp;(isCancelled())&nbsp;break;<\/p>\n<p>}<\/p>\n<p>return&nbsp;totalSize;<\/p>\n<p>}<\/p>\n<p>protected&nbsp;void&nbsp;onProgressUpdate(Integer...&nbsp;progress)&nbsp;{<br \/>\n  <!-- --><\/p>\n<p>setProgressPercent(progress[0]);<\/p>\n<p>}<\/p>\n<p>protected&nbsp;void&nbsp;onPostExecute(Long&nbsp;result)&nbsp;{<br \/>\n  <!-- --><\/p>\n<p>showDialog(\"Downloaded&nbsp;\"&nbsp;+&nbsp;result&nbsp;+&nbsp;\"&nbsp;bytes\");<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>Once&nbsp;created,&nbsp;a&nbsp;task&nbsp;is&nbsp;executed&nbsp;very&nbsp;simply:<\/p>\n<p>new&nbsp;DownloadFilesTask().execute(url1,&nbsp;url2,&nbsp;url3);<\/p>\n<p>AsyncTask's&nbsp;generic&nbsp;types<\/p>\n<p>The&nbsp;three&nbsp;types&nbsp;used&nbsp;by&nbsp;an&nbsp;asynchronous&nbsp;task&nbsp;are&nbsp;the&nbsp;following:<\/p>\n<p>1.&nbsp;Params,&nbsp;the&nbsp;type&nbsp;of&nbsp;the&nbsp;parameters&nbsp;sent&nbsp;to&nbsp;the&nbsp;task&nbsp;upon&nbsp;execution.<\/p>\n<p>2.&nbsp;Progress,&nbsp;the&nbsp;type&nbsp;of&nbsp;the&nbsp;progress&nbsp;units&nbsp;published&nbsp;during&nbsp;the&nbsp;background&nbsp;computation.<\/p>\n<p>3.&nbsp;Result,&nbsp;the&nbsp;type&nbsp;of&nbsp;the&nbsp;result&nbsp;of&nbsp;the&nbsp;background&nbsp;computation.<\/p>\n<p>Not&nbsp;all&nbsp;types&nbsp;are&nbsp;always&nbsp;used&nbsp;by&nbsp;an&nbsp;asynchronous&nbsp;task.&nbsp;To&nbsp;mark&nbsp;a&nbsp;type&nbsp;as&nbsp;unused,&nbsp;simply&nbsp;use&nbsp;the&nbsp;type&nbsp;Void:<\/p>\n<p>private&nbsp;class&nbsp;MyTask&nbsp;extends&nbsp;AsyncTask&nbsp;{&nbsp;...&nbsp;}<\/p>\n<p>The&nbsp;4&nbsp;steps<\/p>\n<p>When&nbsp;an&nbsp;asynchronous&nbsp;task&nbsp;is&nbsp;executed,&nbsp;the&nbsp;task&nbsp;goes&nbsp;through&nbsp;4&nbsp;steps:<\/p>\n<p>1.&nbsp;onPreExecute(),&nbsp;invoked&nbsp;on&nbsp;the&nbsp;UI&nbsp;thread&nbsp;before&nbsp;the&nbsp;task&nbsp;is&nbsp;executed.&nbsp;This&nbsp;step&nbsp;is&nbsp;normally&nbsp;used&nbsp;to&nbsp;setup&nbsp;the&nbsp;task,&nbsp;for&nbsp;instance&nbsp;by&nbsp;showing&nbsp;a&nbsp;progress&nbsp;bar&nbsp;in&nbsp;the&nbsp;user&nbsp;interface.<\/p>\n<p>2.&nbsp;doInBackground(Params...),&nbsp;invoked&nbsp;on&nbsp;the&nbsp;background&nbsp;thread&nbsp;immediately&nbsp;after&nbsp;onPreExecute()&nbsp;finishes&nbsp;executing.&nbsp;This&nbsp;step&nbsp;is&nbsp;used&nbsp;to&nbsp;perform&nbsp;background&nbsp;computation&nbsp;that&nbsp;can&nbsp;take&nbsp;a&nbsp;long&nbsp;time.&nbsp;The&nbsp;parameters&nbsp;of&nbsp;the&nbsp;asynchronous&nbsp;task&nbsp;are&nbsp;passed&nbsp;to&nbsp;this&nbsp;step.&nbsp;The&nbsp;result&nbsp;of&nbsp;the&nbsp;computation&nbsp;must&nbsp;be&nbsp;returned&nbsp;by&nbsp;this&nbsp;step&nbsp;and&nbsp;will&nbsp;be&nbsp;passed&nbsp;back&nbsp;to&nbsp;the&nbsp;last&nbsp;step.&nbsp;This&nbsp;step&nbsp;can&nbsp;also&nbsp;use&nbsp;publishProgress(Progress...)&nbsp;to&nbsp;publish&nbsp;one&nbsp;or&nbsp;more&nbsp;units&nbsp;of&nbsp;progress.&nbsp;These&nbsp;values&nbsp;are&nbsp;published&nbsp;on&nbsp;the&nbsp;UI&nbsp;thread,&nbsp;in&nbsp;the&nbsp;onProgressUpdate(Progress...)&nbsp;step.<\/p>\n<p>3.&nbsp;onProgressUpdate(Progress...),&nbsp;invoked&nbsp;on&nbsp;the&nbsp;UI&nbsp;thread&nbsp;after&nbsp;a&nbsp;call&nbsp;to&nbsp;publishProgress(Progress...).&nbsp;The&nbsp;timing&nbsp;of&nbsp;the&nbsp;execution&nbsp;is&nbsp;undefined.&nbsp;This&nbsp;method&nbsp;is&nbsp;used&nbsp;to&nbsp;display&nbsp;any&nbsp;form&nbsp;of&nbsp;progress&nbsp;in&nbsp;the&nbsp;user&nbsp;interface&nbsp;while&nbsp;the&nbsp;background&nbsp;computation&nbsp;is&nbsp;still&nbsp;executing.&nbsp;For&nbsp;instance,&nbsp;it&nbsp;can&nbsp;be&nbsp;used&nbsp;to&nbsp;animate&nbsp;a&nbsp;progress&nbsp;bar&nbsp;or&nbsp;show&nbsp;logs&nbsp;in&nbsp;a&nbsp;text&nbsp;field.<\/p>\n<p>4.&nbsp;onPostExecute(Result),&nbsp;invoked&nbsp;on&nbsp;the&nbsp;UI&nbsp;thread&nbsp;after&nbsp;the&nbsp;background&nbsp;computation&nbsp;finishes.&nbsp;The&nbsp;result&nbsp;of&nbsp;the&nbsp;background&nbsp;computation&nbsp;is&nbsp;passed&nbsp;to&nbsp;this&nbsp;step&nbsp;as&nbsp;a&nbsp;parameter.<\/p>\n<p>Cancelling&nbsp;a&nbsp;task<\/p>\n<p>A&nbsp;task&nbsp;can&nbsp;be&nbsp;cancelled&nbsp;at&nbsp;any&nbsp;time&nbsp;by&nbsp;invoking&nbsp;cancel(boolean).&nbsp;Invoking&nbsp;this&nbsp;method&nbsp;will&nbsp;cause&nbsp;subsequent&nbsp;calls&nbsp;to&nbsp;isCancelled()&nbsp;to&nbsp;return&nbsp;true.&nbsp;After&nbsp;invoking&nbsp;this&nbsp;method,&nbsp;onCancelled(Object),&nbsp;instead&nbsp;of&nbsp;onPostExecute(Object)&nbsp;will&nbsp;be&nbsp;invoked&nbsp;after&nbsp;doInBackground(Object[])&nbsp;returns.&nbsp;To&nbsp;ensure&nbsp;that&nbsp;a&nbsp;task&nbsp;is&nbsp;cancelled&nbsp;as&nbsp;quickly&nbsp;as&nbsp;possible,&nbsp;you&nbsp;should&nbsp;always&nbsp;check&nbsp;the&nbsp;return&nbsp;value&nbsp;of&nbsp;isCancelled()&nbsp;periodically&nbsp;from&nbsp;doInBackground(Object[]),&nbsp;if&nbsp;possible&nbsp;(inside&nbsp;a&nbsp;loop&nbsp;for&nbsp;instance.)<\/p>\n<p>\u8c03\u7528cancel(...)\u53ef\u4ee5\u7ed3\u675fAsyncTask.<\/p>\n<p>cancel&nbsp;\u53ef\u4ee5\u5728\u4efb\u610f\u65f6\u523b\u8c03\u7528\u3002<\/p>\n<p>\u5728\u8bbe\u8ba1\u5f02\u6b65\u4efb\u52a1\u7684\u65f6\u5019\uff0ccancel\u7684\u539f\u7406\u503c\u5f97\u53c2\u8003\uff0c\u5927\u6982\u662f\u8fd9\u6837\uff1a<\/p>\n<p>Cancel\u8bbe\u7f6e\u4e00\u4e2a\u6807\u5fd7\u4f4d\uff0c\u5404\u4e2a\u9636\u6bb5\u7684\u65b9\u6cd5\u90fd\u4f1a\u53bb\u68c0\u67e5\u8fd9\u4e2a\u6807\u5fd7\u4f4d\u3002<\/p>\n<p>Threading&nbsp;rules<\/p>\n<p>\u00b7&nbsp;The&nbsp;AsyncTask&nbsp;class&nbsp;must&nbsp;be&nbsp;loaded&nbsp;on&nbsp;the&nbsp;UI&nbsp;thread.&nbsp;This&nbsp;is&nbsp;done&nbsp;automatically&nbsp;as&nbsp;of&nbsp;JELLY_BEAN.<\/p>\n<p>\u00b7&nbsp;The&nbsp;task&nbsp;instance&nbsp;must&nbsp;be&nbsp;created&nbsp;on&nbsp;the&nbsp;UI&nbsp;thread.<\/p>\n<p>\u00b7&nbsp;execute(Params...)&nbsp;must&nbsp;be&nbsp;invoked&nbsp;on&nbsp;the&nbsp;UI&nbsp;thread.<\/p>\n<p>\u00b7&nbsp;The&nbsp;task&nbsp;can&nbsp;be&nbsp;executed&nbsp;only&nbsp;once&nbsp;(an&nbsp;exception&nbsp;will&nbsp;be&nbsp;thrown&nbsp;if&nbsp;a&nbsp;second&nbsp;execution&nbsp;is&nbsp;attempted.)<\/p>\n<p>1.AsyncTask\u5fc5\u987b\u88ab\u5728UI\u7ebf\u7a0b\u52a0\u8f7d(be&nbsp;loaded)(TODO\u6709\u7a7a\u67e5\u4e0b&nbsp;\u8fd9\u53e5\u5565\u610f\u601d)<\/p>\n<p>2.AsyncTask\u7c7b\u7684\u5bf9\u8c61\u5b9e\u4f8b\uff0c\u5fc5\u987b\u5728UI\u7ebf\u7a0b\u521b\u5efa(created\uff0c&nbsp;\u5e94\u8be5\u5c31\u662fnew)<\/p>\n<p>3.execute(\u3002\u3002\u3002)\u65b9\u6cd5\u5fc5\u987b\u5728UI\u7ebf\u7a0b\u8c03\u7528<\/p>\n<p>4.\u3002\u3002\u3002<\/p>\n<p>5.\u4e00\u4e2a\u5b9e\u4f8b\u53ea\u80fd\u6267\u884c\u4e00\u6b21<\/p>\n<p>Memory&nbsp;observability<\/p>\n<p>AsyncTask&nbsp;guarantees&nbsp;that&nbsp;all&nbsp;callback&nbsp;calls&nbsp;are&nbsp;synchronized&nbsp;in&nbsp;such&nbsp;a&nbsp;way&nbsp;that&nbsp;the&nbsp;following&nbsp;operations&nbsp;are&nbsp;safe&nbsp;without&nbsp;explicit&nbsp;synchronizations.<\/p>\n<p>\u00b7&nbsp;Set&nbsp;member&nbsp;fields&nbsp;in&nbsp;the&nbsp;constructor&nbsp;or&nbsp;onPreExecute(),&nbsp;and&nbsp;refer&nbsp;to&nbsp;them&nbsp;in&nbsp;doInBackground(Params...).<\/p>\n<p>\u5185\u5b58\u53ef\u89c1\u6027<\/p>\n<p>AsyncTask\u5185\u7f6e\u540c\u6b65\u673a\u5236<\/p>\n<p>onPreExecute&nbsp;---&gt;&nbsp;doInBackground&nbsp;---&gt;&nbsp;onProgressUpdate\/onPostExecute\u662f\u4e32\u884c\u6267\u884c\u7684\u3002<\/p>\n<p>\u53ef\u4ee5\u5728onPreExecute\u8bbe\u7f6e\u6210\u5458\u5c5e\u6027\uff0c\u5728doInBackground\u4e2d\u8bbf\u95ee\u3002<\/p>\n<p>\u53ef\u4ee5\u5728doInBackground\u8bbe\u7f6e\u6210\u5458\u5c5e\u6027\uff0c\u5728onProgressUpdate\/onPostExecute\u4e2d\u8bbf\u95ee<\/p>\n<p>Order&nbsp;of&nbsp;execution<\/p>\n<p>When&nbsp;first&nbsp;introduced,&nbsp;AsyncTasks&nbsp;were&nbsp;executed&nbsp;serially&nbsp;on&nbsp;a&nbsp;single&nbsp;background&nbsp;thread.&nbsp;Starting&nbsp;with&nbsp;DONUT,&nbsp;this&nbsp;was&nbsp;changed&nbsp;to&nbsp;a&nbsp;pool&nbsp;of&nbsp;threads&nbsp;allowing&nbsp;multiple&nbsp;tasks&nbsp;to&nbsp;operate&nbsp;in&nbsp;parallel.&nbsp;Starting&nbsp;with&nbsp;HONEYCOMB,&nbsp;tasks&nbsp;are&nbsp;executed&nbsp;on&nbsp;a&nbsp;single&nbsp;thread&nbsp;to&nbsp;avoid&nbsp;common&nbsp;application&nbsp;errors&nbsp;caused&nbsp;by&nbsp;parallel&nbsp;execution.<\/p>\n<p>\u591a\u4e2aAsyncTask\u7684\u6267\u884c\u987a\u5e8f<\/p>\n<p>1.\u6700\u521d&nbsp;---&nbsp;donut\u4e4b\u524d\uff1a\u5355\u7ebf\u7a0b\u4e32\u884c\u6267\u884c<\/p>\n<p>2.Donut&nbsp;---&nbsp;honeycomb\u4e4b\u524d&nbsp;\uff1a&nbsp;\u7ebf\u7a0b\u6c60\u5e76\u884c\u6267\u884c<\/p>\n<p>3.Honeycomb&nbsp;---\u73b0\u5728&nbsp;\uff1a\u5355\u7ebf\u7a0b\u4e32\u884c\u6267\u884c<\/p>\n<p>Honeycomb&nbsp;\u63d0\u4f9b\u4e86\u4e00\u4e2a\u65b9\u6cd5executeOnExecutor\uff0c\u53ef\u4ee5\u5e76\u884c\u6267\u884c\u591a\u4e2aAsyncTask<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"android taskaffinity_Android\u670d\u52a1\u76d1\u89c6\u624b\u673aAndroid\u591a\u7ebf\u7a0b\u8f85\u52a9\u7c7b\u8f85\u52a9\u7c7b\u533a\u5206\u4e8e\u57fa\u7840\u7c7b\u57fa\u7840\u7c7b\u5305\u62ecjava\u672c\u6765\u7684\u591a\u7ebf\u7a0b\u7c7b\u3001android\u7684h...","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"_links":{"self":[{"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/posts\/4945"}],"collection":[{"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/comments?post=4945"}],"version-history":[{"count":0,"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/posts\/4945\/revisions"}],"wp:attachment":[{"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/media?parent=4945"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/categories?post=4945"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mushiming.com\/wp-json\/wp\/v2\/tags?post=4945"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}