最近在项目中有个下载模块,我介绍一下我的实现思路:
1.多线程:自己开启另一个线程来进行下载处理(可以直接使用Handler:不推荐使用、Thread类以及AsynTask等方式的线程实现)
2.服务:开启一个下载的Service来专门进行下载操作
当然上面两种凡是实现都是没有问题的,也能达到下载的功能实现。可总觉得都各有不好的地方。
首先,线程的方式,因为线程的生命周期主要依赖于它所在的进程,当用户的当前应用经常处于后台模式时就很可能被系统回收从而导致下载线程也被杀死,下载可能没有完成,毕竟一般的下载任务都是比较长的。当然你也可以使用preference或数据库记录下载的地址、进度等内容再实现断点续传。可是总是感觉比较麻烦。再说那个服务的方式,当然一些比较正规的大公司的APP一般使用Service的方式比较多。可能他们更加的重视用户的用户体验和数据功能的完整性。毕竟服务进程被杀死的可能性低得多,这样比较能保障用户下载的数据能够完成。当然这种方式我个人也比较倾向,你看腾讯之类的公司的APP中总是有很多后台Service。但是我觉得下载这个任务应该属于短暂性的后台任务,如果非有个后台常驻服务总是让你很不爽。
IntentService这个家伙简直就是为了下载这类任务准备的啊,它是异步处理工作的服务,还能自动关闭回收。
工作流程也非常简单,客户端通过startService(Intent) 方法来调用,服务启动后,开启worker线程来顺序处理intent的任务。注意这里,一个intentService可以处理多个任务,只不过是一个接着一个的顺序来处理的;AsyncTask通常情况是每个任务启动一个新的asycnTask来工作,一个asyncTask只能使用一次,当你想再次使用的话,只好再new一个任务,否则要报异常的。从表象上看,这是两者的区别。当任务完成后,IntentService自动停止。IntentService是继承自Service的,从源码上看,它是Service、HandlerThread和Handler的强强联合。源码也比AsyncTask简单,有兴趣的童鞋可以去看看。
下面说说它的用法,和AsyncTask一样,使用IntentService必须要写一个类然后继承它。
因为IntentService本身是继承自Service,所以在使用的时候要先在AndroidManifest.xml中注册,否则报错:Unable to start service Intent not found
IntentService有7个方法,其中最重要的是onHandleIntent(),在这里调用worker线程来处理工作,每次只处理一个intent,像上面描述的,如果有多个,它会顺序处理,直到最后一个处理完毕,然后关闭自己。一点都不用我们操心,多好。
再介绍另一个很有意思的方法,setIntentRedelivery()。从字面理解是设置intent重投递。如果设置为true,onStartCommand(Intent, int, int)将会返回START_REDELIVER_INTENT,如果onHandleIntent(Intent)返回之前进程死掉了,那么进程将会重新启动,intent重新投递,如果有大量的intent投递了,那么只保证最近的intent会被重投递。这个机制也很好,大家可以尝试着用。
andorid提供这个处理耗时任务的工具,为我们开发者带来了极大的便利。跟随源码,又可以让我们的水平上升一个档次。看来,android提供的文档和例子就是一个宝库,我们要好好的利用起来!同时一些源码也可以作为我们构造某个功能模块的模板样例!