`
cynhafa
  • 浏览: 154871 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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. 队列类

  1. public class DownLoadQueue{
  2. public int id; //队列id , 该id标识了一条下载线程和Notification
  3. public String name; // 队列名称,用于显示在Notification中
  4. public int progress = 0; //进度,一个0-100之前的整数,标识百分比
  5. public boolean isCancel = fale; //是否已经取消,该开关用于取消下载

2. Service类:

  1. public class DownloadService extends Service{
  2. private Map<integer><span class="sh_normal"> </span>downLoadQueue<span class="sh_symbol">;</span> <span class="sh_comment">//下载队列,格式:</span><id><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> <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> <span class="sh_symbol">....</span> </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> <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> <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> <span class="sh_keyword">public</span> <span class="sh_usertype">Map</span><integer><span class="sh_normal"> </span><span class="sh_function">getQueueList</span><span class="sh_symbol">()</span><span class="sh_cbracket">{</span><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> <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></integer> </li></id></integer>

3. Activity类:

  1. public class DownLoadActivity{
  2. private Handler handler = new Handler();
  3. private DownloadService downLoadService;
  4. private ServiceConnection serviceConnection = new ServiceConnection()
  5. {
  6. // 连接服务失败后,该方法被调用
  7. @Override
  8. public void onServiceDisconnected(ComponentName name)
  9. {
  10. downLoadService = null;
  11. Toast.makeText(DownLoadActivity.this, "Service Failed.", Toast.LENGTH_LONG).show();
  12. }
  13. // 成功连接服务后,该方法被调用。在该方法中可以获得downLoadService对象
  14. @Override
  15. public void onServiceConnected(ComponentName name, IBinder service)
  16. {
  17. // 获得downLoadService对象
  18. downLoadService = ((DownLoadService.DownLoadServiceBinder) service).getService();
  19. Toast.makeText(DownLoadActivity.this, "Service Connected.", Toast.LENGTH_LONG).show();
  20. }
  21. };
  22. @Override
  23. public void onCreate(Bundle savedInstanceState){
  24. super.onCreate(savedInstanceState);
  25. Intent serviceIntent = new Intent(DownLoadActivity.this,DownloadService.class);
  26. bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
  27. startService(serviceIntent);
  28. .....
  29. }
  30. private void startDownLoad(){
  31. DownLoadQueue queue = new DownLoadQueue();
  32. queue.id = 1;
  33. queue.name = "愤怒的小鸟"
  34. ...
  35. downLoadService.addDownLoad(queue);
  36. ....
  37. }
  38. @Override
  39. public void onDestroy(){
  40. super.onDestroy();
  41. unbindService(new Intent(DownLoadActivity.this,DownloadService.class));
  42. }

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

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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics