Android实现Service后台下载Notification进度条

原文网址:http://www.obatu.com/android-service-download-notification-progressbar/

 

 最近的项目中,有一个需求是 【后台下载+多线程+Notificaton进度条】的应用。要求有一个Service做下载服务,Notification中显示一进度条,进度条由Service来更新。
花了个把小时在网上找代码,没有一个完美的方案,最后根据片段信息,自己实现了。贴出来分享一下。

思路:

  • 1. 有一个提供队列下载的Service
  • 2. 该Service可以绑定,绑定的时候返回本身实例
  • 3. 该Service提供方法给绑定了该Service的Activity,Activity可以调用Service的提供的方法,给Service添加队列
  • 4. 该Service提供了当前下载队列的信息,信息包括下载的名称,下载进度,Activity通过接口读取队列信息用于操作,如:取消


实现:

1. 队列类

<ol sizcache="19" sizset="3"><li><span class="sh_keyword">public</span> <span class="sh_keyword">class</span><span class="sh_normal"> </span><span class="sh_classname">DownLoadQueue</span><span class="sh_cbracket">{</span></li><li> </li><li>    <span class="sh_keyword">public</span> <span class="sh_type">int</span> id<span class="sh_symbol">;</span> <span class="sh_comment">//队列id , 该id标识了一条下载线程和Notification</span></li><li> </li><li>    <span class="sh_keyword">public</span> <span class="sh_usertype">String</span><span class="sh_normal"> </span>name<span class="sh_symbol">;</span> <span class="sh_comment">// 队列名称,用于显示在Notification中</span></li><li> </li><li>     <span class="sh_keyword">public</span> <span class="sh_type">int</span> progress <span class="sh_symbol">=</span> <span class="sh_number">0</span><span class="sh_symbol">;</span> <span class="sh_comment">//进度,一个0-100之前的整数,标识百分比</span></li><li> </li><li>     <span class="sh_keyword">public</span> <span class="sh_type">boolean</span> isCancel <span class="sh_symbol">=</span> fale<span class="sh_symbol">;</span> <span class="sh_comment">//是否已经取消,该开关用于取消下载</span></li><li> </li></ol>

2. Service类:

<ol sizcache="19" sizset="4"><li>  <span class="sh_keyword">public</span> <span class="sh_keyword">class</span><span class="sh_normal"> </span><span class="sh_classname">DownloadService</span> <span class="sh_keyword">extends</span> Service<span class="sh_cbracket">{</span></li><li> </li><li>           <span class="sh_keyword">private</span> <span class="sh_usertype">Map</span><integer downloadqueue=""><span class="sh_normal"> </span>downLoadQueue<span class="sh_symbol">;</span> <span class="sh_comment">//下载队列,格式:</span><id></id></integer></li><li> </li><li>             <span class="sh_keyword">private</span> <span class="sh_usertype">Binder</span><span class="sh_normal"> </span>serviceBinder <span class="sh_symbol">=</span> <span class="sh_keyword">new</span> <span class="sh_function">DownLoadServiceBinder</span><span class="sh_symbol">();</span></li><li> </li><li>               <span class="sh_comment">// Activity绑定后,会自动条用这个方法</span></li><li>               @Override</li><li>               <span class="sh_keyword">public</span> <span class="sh_usertype">IBinder</span><span class="sh_normal"> </span><span class="sh_function">onBind</span><span class="sh_symbol">(</span><span class="sh_usertype">Intent</span><span class="sh_normal"> </span>intent<span class="sh_symbol">)</span></li><li>               <span class="sh_cbracket">{</span></li><li>                    Log<span class="sh_symbol">.</span><span class="sh_function">d</span><span class="sh_symbol">(</span><span class="sh_string">"DownloadService"</span><span class="sh_symbol">,</span> <span class="sh_string">"onBind"</span><span class="sh_symbol">);</span></li><li>                    <span class="sh_keyword">return</span> serviceBinder<span class="sh_symbol">;</span></li><li>               <span class="sh_cbracket">}</span> </li><li> </li><li>               <span class="sh_symbol">....</span></li><li> </li><li>               <span class="sh_keyword">private</span> <span class="sh_type">void</span> <span class="sh_function">startDownLoad</span><span class="sh_symbol">(</span><span class="sh_usertype">DownLoadQueue</span><span class="sh_normal"> </span>queue<span class="sh_symbol">)</span><span class="sh_cbracket">{</span></li><li>                    <span class="sh_keyword">new</span> <span class="sh_function">Thread</span><span class="sh_symbol">()</span><span class="sh_cbracket">{</span></li><li>                         <span class="sh_keyword">public</span> <span class="sh_type">void</span> <span class="sh_function">run</span><span class="sh_symbol">()</span><span class="sh_cbracket">{</span></li><li>                              <span class="sh_comment">//进行下载工作,这里需要更新downLoadQueue中对应的queue的进度信息</span></li><li>                              <span class="sh_comment">//使用Handler更新notification信息</span></li><li>                              <span class="sh_symbol">....</span></li><li>                         <span class="sh_cbracket">}</span></li><li> </li><li>                    <span class="sh_cbracket">}</span><span class="sh_symbol">.</span><span class="sh_function">start</span><span class="sh_symbol">();</span></li><li>               <span class="sh_cbracket">}</span></li><li> </li><li>               <span class="sh_keyword">public</span> <span class="sh_type">void</span> <span class="sh_function">addQueue</span><span class="sh_symbol">(</span><span class="sh_usertype">DownLoadQueue</span><span class="sh_normal"> </span>queue<span class="sh_symbol">)</span><span class="sh_cbracket">{</span></li><li>                    <span class="sh_keyword">this</span><span class="sh_symbol">.</span>downLoadQueue<span class="sh_symbol">.</span><span class="sh_function">add</span><span class="sh_symbol">(</span>queue<span class="sh_symbol">.</span>id<span class="sh_symbol">,</span>queue<span class="sh_symbol">);</span></li><li>                    <span class="sh_keyword">this</span><span class="sh_symbol">.</span><span class="sh_function">startDownLoad</span><span class="sh_symbol">(</span>queue<span class="sh_symbol">);</span></li><li>               <span class="sh_cbracket">}</span></li><li> </li><li>               <span class="sh_keyword">public</span> <span class="sh_usertype">Map</span><integer downloadqueue=""><span class="sh_normal"> </span><span class="sh_function">getQueueList</span><span class="sh_symbol">()</span><span class="sh_cbracket">{</span></integer></li><li>                    <span class="sh_keyword">return</span> <span class="sh_keyword">this</span><span class="sh_symbol">.</span>downLoadQueue<span class="sh_symbol">;</span></li><li>               <span class="sh_cbracket">}</span></li><li> </li><li>             <span class="sh_keyword">public</span> <span class="sh_keyword">class</span><span class="sh_normal"> </span><span class="sh_classname">public</span> DownLoadServiceBinder <span class="sh_keyword">extends</span> Binder<span class="sh_cbracket">{</span></li><li>                  <span class="sh_keyword">public</span> <span class="sh_usertype">DownloadService</span><span class="sh_normal"> </span><span class="sh_function">getService</span><span class="sh_symbol">()</span><span class="sh_cbracket">{</span></li><li>                         <span class="sh_keyword">return</span> DownloadService<span class="sh_symbol">.</span><span class="sh_keyword">this</span><span class="sh_symbol">;</span></li><li>                    <span class="sh_cbracket">}</span></li><li>             <span class="sh_cbracket">}</span></li></ol>

3. Activity类:

<ol sizcache="19" sizset="5"><li><span class="sh_keyword">public</span> <span class="sh_keyword">class</span><span class="sh_normal"> </span><span class="sh_classname">DownLoadActivity</span><span class="sh_cbracket">{</span></li><li>          <span class="sh_keyword">private</span> <span class="sh_usertype">Handler</span><span class="sh_normal"> </span>handler <span class="sh_symbol">=</span> <span class="sh_keyword">new</span> <span class="sh_function">Handler</span><span class="sh_symbol">();</span></li><li>          <span class="sh_keyword">private</span> <span class="sh_usertype">DownloadService</span><span class="sh_normal"> </span>downLoadService<span class="sh_symbol">;</span></li><li>          <span class="sh_keyword">private</span> <span class="sh_usertype">ServiceConnection</span><span class="sh_normal"> </span>serviceConnection <span class="sh_symbol">=</span> <span class="sh_keyword">new</span> <span class="sh_function">ServiceConnection</span><span class="sh_symbol">()</span></li><li>          <span class="sh_cbracket">{</span></li><li>               <span class="sh_comment">// 连接服务失败后,该方法被调用</span></li><li>               @Override</li><li>               <span class="sh_keyword">public</span> <span class="sh_type">void</span> <span class="sh_function">onServiceDisconnected</span><span class="sh_symbol">(</span><span class="sh_usertype">ComponentName</span><span class="sh_normal"> </span>name<span class="sh_symbol">)</span></li><li>               <span class="sh_cbracket">{</span></li><li>                    downLoadService <span class="sh_symbol">=</span> <span class="sh_keyword">null</span><span class="sh_symbol">;</span></li><li>                    Toast<span class="sh_symbol">.</span><span class="sh_function">makeText</span><span class="sh_symbol">(</span>DownLoadActivity<span class="sh_symbol">.</span><span class="sh_keyword">this</span><span class="sh_symbol">,</span> <span class="sh_string">"Service Failed."</span><span class="sh_symbol">,</span> Toast<span class="sh_symbol">.</span>LENGTH_LONG<span class="sh_symbol">).</span><span class="sh_function">show</span><span class="sh_symbol">();</span></li><li>               <span class="sh_cbracket">}</span></li><li>               <span class="sh_comment">// 成功连接服务后,该方法被调用。在该方法中可以获得downLoadService对象</span></li><li>               @Override</li><li>               <span class="sh_keyword">public</span> <span class="sh_type">void</span> <span class="sh_function">onServiceConnected</span><span class="sh_symbol">(</span><span class="sh_usertype">ComponentName</span><span class="sh_normal"> </span>name<span class="sh_symbol">,</span> <span class="sh_usertype">IBinder</span><span class="sh_normal"> </span>service<span class="sh_symbol">)</span></li><li>               <span class="sh_cbracket">{</span></li><li>                    <span class="sh_comment">// 获得downLoadService对象</span></li><li>                    downLoadService <span class="sh_symbol">=</span> <span class="sh_symbol">((</span>DownLoadService<span class="sh_symbol">.</span>DownLoadServiceBinder<span class="sh_symbol">)</span> service<span class="sh_symbol">).</span><span class="sh_function">getService</span><span class="sh_symbol">();</span></li><li>                    Toast<span class="sh_symbol">.</span><span class="sh_function">makeText</span><span class="sh_symbol">(</span>DownLoadActivity<span class="sh_symbol">.</span><span class="sh_keyword">this</span><span class="sh_symbol">,</span> <span class="sh_string">"Service Connected."</span><span class="sh_symbol">,</span> Toast<span class="sh_symbol">.</span>LENGTH_LONG<span class="sh_symbol">).</span><span class="sh_function">show</span><span class="sh_symbol">();</span></li><li>               <span class="sh_cbracket">}</span></li><li>          <span class="sh_cbracket">}</span><span class="sh_symbol">;</span> </li><li> </li><li>          @Override</li><li>          <span class="sh_keyword">public</span> <span class="sh_type">void</span> <span class="sh_function">onCreate</span><span class="sh_symbol">(</span><span class="sh_usertype">Bundle</span><span class="sh_normal"> </span>savedInstanceState<span class="sh_symbol">)</span><span class="sh_cbracket">{</span></li><li>               <span class="sh_keyword">super</span><span class="sh_symbol">.</span><span class="sh_function">onCreate</span><span class="sh_symbol">(</span>savedInstanceState<span class="sh_symbol">);</span></li><li>               <span class="sh_usertype">Intent</span><span class="sh_normal"> </span>serviceIntent <span class="sh_symbol">=</span> <span class="sh_keyword">new</span> <span class="sh_function">Intent</span><span class="sh_symbol">(</span>DownLoadActivity<span class="sh_symbol">.</span><span class="sh_keyword">this</span><span class="sh_symbol">,</span>DownloadService<span class="sh_symbol">.</span><span class="sh_keyword">class</span><span class="sh_symbol">);</span></li><li>               <span class="sh_function">bindService</span><span class="sh_symbol">(</span>serviceIntent<span class="sh_symbol">,</span> serviceConnection<span class="sh_symbol">,</span> Context<span class="sh_symbol">.</span>BIND_AUTO_CREATE<span class="sh_symbol">);</span></li><li>               <span class="sh_function">startService</span><span class="sh_symbol">(</span>serviceIntent<span class="sh_symbol">);</span></li><li>               <span class="sh_symbol">.....</span></li><li>          <span class="sh_cbracket">}</span></li><li> </li><li>          <span class="sh_keyword">private</span> <span class="sh_type">void</span> <span class="sh_function">startDownLoad</span><span class="sh_symbol">()</span><span class="sh_cbracket">{</span></li><li>               <span class="sh_usertype">DownLoadQueue</span><span class="sh_normal"> </span>queue <span class="sh_symbol">=</span> <span class="sh_keyword">new</span> <span class="sh_function">DownLoadQueue</span><span class="sh_symbol">();</span></li><li>               queue<span class="sh_symbol">.</span>id <span class="sh_symbol">=</span> <span class="sh_number">1</span><span class="sh_symbol">;</span></li><li>               queue<span class="sh_symbol">.</span>name <span class="sh_symbol">=</span> <span class="sh_string">"愤怒的小鸟"</span></li><li>               <span class="sh_symbol">...</span></li><li>               downLoadService<span class="sh_symbol">.</span><span class="sh_function">addDownLoad</span><span class="sh_symbol">(</span>queue<span class="sh_symbol">);</span></li><li>               <span class="sh_symbol">....</span></li><li>          <span class="sh_cbracket">}</span></li><li> </li><li>          @Override</li><li>          <span class="sh_keyword">public</span> <span class="sh_type">void</span> <span class="sh_function">onDestroy</span><span class="sh_symbol">()</span><span class="sh_cbracket">{</span></li><li>               <span class="sh_keyword">super</span><span class="sh_symbol">.</span><span class="sh_function">onDestroy</span><span class="sh_symbol">();</span></li><li>               <span class="sh_function">unbindService</span><span class="sh_symbol">(</span><span class="sh_keyword">new</span> <span class="sh_function">Intent</span><span class="sh_symbol">(</span>DownLoadActivity<span class="sh_symbol">.</span><span class="sh_keyword">this</span><span class="sh_symbol">,</span>DownloadService<span class="sh_symbol">.</span><span class="sh_keyword">class</span><span class="sh_symbol">));</span></li><li>          <span class="sh_cbracket">}</span></li></ol>

4. 在Service中更新Notification时,不能过于频繁,否则会造成卡机。notification使用RemoteView来自定义Notification,加入进度条加入各种说明文字,等等。

以上文字只是简单的提及了一些思路。在项目中已经实现。下次修改完善后贴上来分享。希望能够将该功能做成一个独立的Service供大家在项目中嵌入使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值