這近兩天沒有做什麼事情,就做了一個下載管理的的功能, 寫好供項目組中其他人員調用,複用我的下載功能。
我們產品多處用到的下載附件功能, 同時支援的附件的管理: 查看,刪除,轉寄
點擊下載的時候,顯示下載的進度,當前有幾個待下載的,完成了幾個下載的,下載完的可以進行查看,刪除,轉寄
大家也知道,下載很耗時,所以我用了service 進行後台下載,說道後台下載就說道了更新問題。 更新很麻煩,需要監控下載完成沒有,又不能重複下載,又要提示下載完成,又要提示該附件是否正在下載。一系列的問題出現咋辦? service不能直接跟activity通訊(可以通訊,通過aidl,但沒有那沒牛逼,也沒去研究那東西)所以咋辦:
對android架構很熟悉的話,就不用著急了,因為android在這方面提供多方面的支援,有Intent ,多個activit直接通訊,回調,很方便 ,有contentPrevider 訪問資料,擷取,操作也很方便,有broadcastRecever, 提醒,通訊很方便,service 提供了後台完美的運行,跟pc 後台進程一樣為你默默的奉獻, android 各組件都很靈活,易用,非常的低耦合 ,只要你開發過android應用,就可以隨便的使用各組件來搭建一個自己的資料擷取架構。
不多說了,今天的附件下載是這樣的,通過service在後台下載, 通過註冊廣播來進行資料的跟新,和進度顯示, 同時結合 android 通知notification 和handle 非同步呼叫,進行資料的提醒,因為在service中,必須開始一個線程來操作耗時的操作,service只是一個後台啟動並執行服務,他只保證他的生命週期足夠長來進行的你的操作,所以必須開啟一個線程,再通過handle進行資料的提醒:
主要說明下, 在service中通過在oncreat()中開啟一個線程,輪訓ArrayList<AttachmentTask> 我這個附件下載的任務list ,ArrayList<AttachmentTask> 他維護的是一個當前下載的任務,每當下載完一個移除一個,同時下載完後添加到資料庫。 不下載的時候,關掉該服務,現在該下載服務只是初版,有待進一步的最佳化,有什麼好的建議可以留言:
轉載請..:http://blog.csdn.net/liao3841054/article/details/7583003
/* * @project C6Client * @package com.jh.c6.service * @file DownloadService.java * @version 1.0 * @author liaoyp * @time 2012-5-17 上午2:55:19 */package com.jh.c6.service;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.URL;import java.net.URLConnection;import java.util.ArrayList;import java.util.List;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.Service;import android.content.Intent;import android.os.Handler;import android.os.IBinder;import android.widget.Toast;import com.jh.c6.activity.C6ClientActivity;import com.jh.c6.activity.DownloadMangerActivity;import com.jh.c6.activity.R;import com.jh.c6.entity.AttachmentTask;import com.jh.c6.exception.POAException;import com.jh.c6.impl.DownloadDB;import com.jh.c6.util.Configure;public class DownloadService extends Service implements Runnable{private NotificationManager manager;private Notification notif;private Intent intent;Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {if(msg.what == 1){Toast.makeText(getApplicationContext(), "該附件已下載", 500).show();startActivity();}else if(msg.what == 2){startActivity();Toast.makeText(getApplicationContext(), "該附件正在下載", 500).show();}else if(msg.what == 3){//startActivity();Toast.makeText(getApplicationContext(), "伺服器不存在該附件!", 500).show();}else{manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);Notification notification = new Notification(R.drawable.ic_launcher,"附件下載中",System.currentTimeMillis());intent = new Intent();intent.setClass(getApplicationContext(), DownloadMangerActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_NEW_TASK);PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),100, intent, PendingIntent.FLAG_UPDATE_CURRENT);notification.setLatestEventInfo(getApplicationContext(), "附件下載", "下載完成!", pendingIntent);manager.notify(101, notification);Toast.makeText(getApplicationContext(), "下載完成", 500).show();}};};//static LinkedList<AttachmentTask> attsTask = new LinkedList<AttachmentTask>(); public static ArrayList<AttachmentTask> attsTask = new ArrayList<AttachmentTask>(); public void startActivity(){intent = new Intent();intent.setClass(getApplicationContext(), DownloadMangerActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_NEW_TASK); DownloadService.this.startActivity(intent); }public boolean isRun;public final static int Max = 4;public static boolean stopDownload;static final Object NO_MORE_WORK = new Object();private Thread t;private DownloadDB downloadDB;private Intent download;private File file;@Overridepublic IBinder onBind(Intent intent) {return null;}/** * 最大限制 * @return */public static boolean IsMaxNum (){return attsTask.size()>=Max? true:false;}/** * 工作清單中是否存在還任務 * @param path * @return */public static boolean isDownLoading(String path){for (int i = 0; i < attsTask.size(); i++) {if(attsTask.get(i).getUri().equals(path)){return true;}}return false;}/** * * <code>getTask</code> * @description: TODO(擷取附件總數) * @return * @since 2012-4-18 liaoyp */public static int getTask(){if(UploadService.attsTask !=null)return attsTask.size();else return 0;}/** * 是否下載完成! * @return */public static boolean isDowloadFinshed(){for (int i = 0; i < attsTask.size(); i++) {if(!attsTask.get(i).isOver()){return false;}}return true;}/** * 伺服器位址 * @return */public static List<String> getDownloadServerPath(){List<String> atts = null;if(attsTask !=null && attsTask.size()>0){ atts = new ArrayList<String>();for (int i = 0; i < attsTask.size(); i++) {if(attsTask.get(i).isOver()){atts.add(attsTask.get(i).getServerPath());}}return atts;}return atts;}@Overridepublic void onCreate() {super.onCreate(); isRun= true; t = new Thread(this); t.start();}@Overridepublic void onStart(Intent intent, int startId) {// TODO Auto-generated method stubsuper.onStart(intent, startId);if(intent !=null &&intent.getExtras() !=null){if(t == null){ t = new Thread(this); t.start();}String uri = (String) intent.getExtras().get("uri");if(uri !=null){for (int i = attsTask.size() -1; i >= 0; i--) {if(attsTask.get(i).getUri().equals(uri)){stopDownload = true;attsTask.remove(i);System.out.println("cancle ---->"+attsTask.size());this.sendBroadcast(new Intent(C6ClientActivity.updateDowload));}}}}}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}@Overridepublic void run() {while(isRun){try {if (attsTask.size() > 0) {for (int i = 0; i <attsTask.size(); i++) {AttachmentTask task = attsTask.get(i);if(! task.isUnSart()){download(attsTask.get(i));}}} else {try {Thread.sleep(500);} catch (Exception e) {}}}catch(Exception e){System.out.println("error-----------------"+e);}}}private void download(AttachmentTask task) throws POAException {// TODO Auto-generated method stub// 開始上傳 和 更新下載的進度顯示System.out.println("dowenload-----------------1");task.setUnSart(true);task.setSarting(true);if(downloadDB == null){downloadDB = new DownloadDB();}String httpPath ;httpPath = task.getUri(); String loacalPath = downloadDB.getLocalpicPath(DownloadService.this, httpPath); System.out.println("localPath : "+loacalPath); if(loacalPath == null){ boolean b = isDownLoading(httpPath); if(b){ // 發送廣播通知 removeTask(task); handler.sendEmptyMessage(2); }else{ // 下載 startDowload(task); }// Toast.makeText(getApplicationContext(), "開始下載", 500).show(); startDowload(task); }else{ File file = new File(loacalPath); if( ! file.exists()){ // 下載 startDowload(task); }else{ // 跳到附件管理介面 removeTask(task); handler.sendEmptyMessage(1); } }}public void startDowload(AttachmentTask task){InputStream is = null;FileOutputStream fos = null;String httpPath = "";try {httpPath = (Configure.IPADDRESS.replaceAll("POSTServiceForAndroid.svc", "")+"FileOutSteam.aspx?FileID="+task.getUri());System.out.println("http: "+httpPath);URLConnection connetion = new URL(httpPath).openConnection(); is=connetion.getInputStream();//HttpGet httpGet = new HttpGet(task.getUri());//HttpClient client = new DefaultHttpClient();//HttpParams httpParams = client.getParams();//HttpConnectionParams.setConnectionTimeout(httpParams,5000);//HttpConnectionParams.setSoTimeout(httpParams, 10000);//HttpResponse httpResponse = client.execute(httpGet);//if (httpResponse.getStatusLine().getStatusCode() == 200) {//// is = httpResponse.getEntity().getContent();// 開始下載apk檔案 String path = Configure.DATADIR+Configure.DownloadFile + "/"+task.getServerPath(); file = new File(path); if( ! file.exists()){ file.createNewFile(); } fos = new FileOutputStream(file);byte[] buffer = new byte[2048];int count = 0;while ((count = is.read(buffer)) != -1) {if (stopDownload) { break ;}fos.write(buffer, 0, count);// 進行進度跟新 long current= task.getCurrentProgress();current =task.getCurrentProgress() +count;task.setCurrentProgress(current);// send broadCast to mangeAttachmengActivitydownload = new Intent(C6ClientActivity.DowloadAction);download.putExtra("type", 0);this.sendBroadcast(download);System.out.println("下載中......");}fos.flush();removeTask(task);if(downloadDB != null){downloadDB.insertPic(DownloadService.this, task.getUri(),path, Configure.ACCOUNTID);}else{new DownloadDB().insertPic(DownloadService.this, task.getUri(),path, Configure.ACCOUNTID);}// 提示下載完成 !//download = new Intent(C6ClientActivity.DowloadAction);//download.putExtra("type", 1);//this.sendBroadcast(download);handler.sendEmptyMessage(0);}catch (FileNotFoundException e) {e.printStackTrace();handler.sendEmptyMessage(3);}catch (IOException e) {e.printStackTrace();} finally{try {if (fos != null) {fos.close();}} catch (IOException e) {e.printStackTrace();}try {if (is != null) { is.close();}} catch (IOException e) {e.printStackTrace();}}}public static void removeTask(AttachmentTask task){if(attsTask.contains(task)){attsTask.remove(task);}}public static void addTask(AttachmentTask task){stopDownload = false;attsTask.add(task);}@Overridepublic void onDestroy() {super.onDestroy();isRun = false;}}