안 드 로 이 드 네 이 티 브 구현 다 중 스 레 드 정지점 인 스 턴 스 코드 다운로드

여러분,고향 사람들,저 는 한 삼 만 에 다시 돌 아 왔 습 니 다.오늘 여러분 께 원생 안 드 로 이 드 로 쓴 다 중 스 레 드 인 터 럽 트 다운로드 Demo 를 가 져 왔 습 니 다.
본문 을 통 해 당신 은 배 울 수 있 습 니 다.
  • SQLite 의 기본 적 인 사용,데이터 뱅 크 의 추가 삭제 와 수정
  • Handler 의 메시지 처리 와 UI 업데이트..
  • Service(주로 다운로드 에 사용)의 진급 과 사용
  • 원생 제 이 슨 파일 분석(다 중 끼 워 넣 기)
  • RandomAccessFile 의 기본 사용 으로 파일 을 세그먼트 로 나 눌 수 있 습 니 다
  • HttpURLConnection 기반 의 큰 파일 다운로드.4.567917.위의 내용 을 결합 시 켜 다 중 스 레 드,정지점 다운 로드 를 실현 한다.
    데 모 는 TV 에서 실행 되 고 있 으 니 그림 에 표 시 된 문 제 는 고민 하지 마 세 요.

    파일 다운로드 데모 가 완료 되 었 습 니 다.업로드 와 설명 이 없습니다.오늘 보 여 드 리 고 설명해 드 리 겠 습 니 다.순수한 것 으로 파일 을 다운로드 할 수 있 습 니 다.안 드 로 이 드 의 기본 적 인 문 제 를 더 많이 이해 해 주 셨 으 면 합 니 다.
    우리 의 사고방식:하나의 데이터베이스,두 개의 테이블,하 나 는 네트워크 데 이 터 를 저장 하 는 데 사용 되 고,하 나 는 로 컬 다운로드 의 진 도 를 저장 하 는 데 사용 된다.다운로드 단 추 를 눌 렀 을 때 DownloadService 를 시작 하여 비교 한 후 다운로드 합 니 다.
    데모 의 디 렉 터 리 구조 부터 살 펴 보 겠 습 니 다.

    모든 절 차 는 코드 에 매우 상세 한 설명 이 있 습 니 다.반드시 코드 를 봐 야 합 니 다(다음은 추출 한 몇 가지 중요 한 설명 입 니 다)!
    데이터베이스 구축 및 DAO
    
    /**
     * Created by Administrator on 2017/3/6 0006.
     */
    public class DownLoadDBHelper extends SQLiteOpenHelper {
      /**
       * DownLoadDBHelper       ,             
       *
       *                
       *     :
       * download_info       
       * localdownload_info         
       *                
       */
      public static String DATABASE_NAME = "downloadFILES.db";
      public static String TABLE_DOWNLOAD_INFO = "download_info";
      public static String TABLE_LOCALDOWNLOAD_INFO = "localdownload_info";
      private static int version = 1;
      public DownLoadDBHelper(Context context) {
        super(context, DATABASE_NAME, null, version);
      }
      @Override
      public void onCreate(SQLiteDatabase db) {
        /*            ,        ,    sqlite  */
        db.execSQL("create table " + TABLE_DOWNLOAD_INFO + "(" + "id integer PRIMARY KEY AUTOINCREMENT," +
            "thread_id integer," + "start_position integer," + "end_position integer," + " completed_size integer," + "url varchar(100))");
        db.execSQL("create table " + TABLE_LOCALDOWNLOAD_INFO + "(" + "id integer PRIMARY KEY AUTOINCREMENT," + "name varchar(50)," +
            "url varchar(100)," + "completedSize integer," + "fileSize integer," + "status integer)");
      }
      @Override
      public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        /*       ,        ,        ,      onUpgrade  
        *              onUpgrade        ,                        。
        * */
        String sql = "drop table if exists " + TABLE_DOWNLOAD_INFO + "";
        String sqlOne = "drop table if exists " + TABLE_LOCALDOWNLOAD_INFO + "";
        db.execSQL(sql);
        db.execSQL(sqlOne);
        onCreate(db);//     ,    。       ,                  
      }
    }
    
    DAO 가 데이터베이스 에 대해 첨삭 검 사 를 진행 하 다
    
    /**
     * Created by ShanCanCan on 2017/3/6 0006.
     */
    public class Dao {
      /*
      * DAO             ,                    。
      * DAO                ,      DAO              ,
      *        ,            ,  ,  ,     。
      *   DAO                     。
      * */
      private static Dao dao;
      private static DownLoadDBHelper dbHelper;
      public static final byte[] Lock = new byte[0]; //           
      public static final byte[] file_Lock = new byte[0];
      public Dao() {//     ,
      }
      public static synchronized Dao getInstance(Context context) {// demo           +                  
        if (dao == null) {
          dao = new Dao();
          dbHelper = new DownLoadDBHelper(context);
        }
        return dao;
      }
      /* public static synchronized Dao getInstance(Context context) {// demo           +                 ,99%        
        if (dao == null) { //                
          dao = new Dao();
          dbHelper = new DownLoadDBHelper(context);
        }
        return dao;
      }*/
      /***************************************    Dao        、 、 、   *********************************************************/
      /**
       *         ,     
       *
       * @param url
       * @return
       */
      public boolean isExist(String url) {
        SQLiteDatabase database = dbHelper.getReadableDatabase(); //   app       
        String sql = "select count(*) from " + TABLE_LOCALDOWNLOAD_INFO + " where url=?"; //    ,           
        Cursor cursor = database.rawQuery(sql, new String[]{url});
        /**
         *
         * @Cursor
         * Cursor       。
         *    moveToFirst()      。
         *            。
         *              。
         * Cursor          。
         *              。
         * Cursor            ,             
         *         :close(),moveToFirst(),moveToNext(),moveToLast(),moveToPrevious(),getColumnCount() 。
         *
         * @rawQuery
         * rawQuery     SQL       ,           ,
         *       “?”     String[]       
         * cursor       ,cursor       ,cursor       。        !!!
         *
         * */
        cursor.moveToFirst();
        int count = cursor.getInt(0);
        cursor.close();
        return count > 0;
      }
      /**
       *        
       *
       * @param url
       * @return
       */
      public boolean isFirstDownload(String url) {
        SQLiteDatabase database = dbHelper.getReadableDatabase();
        String sql = "select count(*) from " + TABLE_DOWNLOAD_INFO + " where url=?";
        Cursor cursor = database.rawQuery(sql, new String[]{url});
        cursor.moveToFirst();
        int count = cursor.getInt(0);
        cursor.close();
        return count == 0;
      }
      /**
       *                 list      
       *
       * @param infos
       * @param context
       */
      public void saveInfos(List<DownLoadInfo> infos, Context context) {
        /**
         *   (Transaction)        ,            。
         *         ,     ,            。
         *     ,SQL Server                ,
         *           。
         *
         *         :   ( Atomicity )、   ( Consistency )、
         *    ( Isolation )    ( Durability )。         ACID   。
         *
         * */
        synchronized (Lock) {
          SQLiteDatabase database = dbHelper.getWritableDatabase();
          database.beginTransaction();//    
          try {//     ,     
            for (DownLoadInfo info : infos) {//for          
              String sql = "insert into " + TABLE_DOWNLOAD_INFO + "(thread_id,start_position, end_position, completed_size, url) values (?,?,?,?,?)";
              Object[] bindArgs = {info.getThreadId(), info.getStartPosition(), info.getEndPosition(), info.getCompletedSize(), info.getUrl()};
              database.execSQL(sql, bindArgs);
            }
            database.setTransactionSuccessful();//    
          } catch (SQLException e) {
            e.printStackTrace();
          } finally {
            database.endTransaction();//    
          }
        }
      }
      /**
       *         
       *
       * @param urlstr
       * @return List<DownloadInfo>           ,              
       */
      public List<DownLoadInfo> getInfos(String urlstr) {
        List<DownLoadInfo> list = new ArrayList<DownLoadInfo>();
        SQLiteDatabase database = dbHelper.getReadableDatabase();
        String sql = "select thread_id, start_position, end_position, completed_size, url from " + TABLE_DOWNLOAD_INFO + " where url=?";
        Cursor cursor = database.rawQuery(sql, new String[]{urlstr});
        while (cursor.moveToNext()) {//  cursor       ,    ,       
          DownLoadInfo info = new DownLoadInfo(cursor.getInt(0), cursor.getInt(1), cursor.getInt(2), cursor.getInt(3), cursor.getString(4));
          list.add(info);
        }
        cursor.close();
        return list;
      }
      /**
       *           ,         ,     
       *
       * @param fileStatus
       **/
      public void insertFileStatus(FileStatus fileStatus) {
        synchronized (file_Lock) {//       ,        
          SQLiteDatabase database = dbHelper.getWritableDatabase();
          database.beginTransaction();
          try {
            String sql = "insert into " + TABLE_LOCALDOWNLOAD_INFO + " (name,url,completedSize,fileSize,status) values(?,?,?,?,?)";
            Object[] bindArgs = {fileStatus.getName(), fileStatus.getUrl(), fileStatus.getCompletedSize(), fileStatus.getFileSize(), fileStatus.getStatus()};
            database.execSQL(sql, bindArgs);
            database.setTransactionSuccessful();
          } catch (SQLException e) {
            e.printStackTrace();
          } finally {
            database.endTransaction();
          }
        }
      }
      /**
       * @param context
       * @param compeletedSize
       * @param threadId
       * @param urlstr             ,                          
       */
      public void updataInfos(int threadId, int compeletedSize, String urlstr, Context context) {
        synchronized (Lock) {
          String sql = "update " + TABLE_DOWNLOAD_INFO + "set completed_size = ? where thread_id =? and url=?";
          String localSql = "update " + TABLE_LOCALDOWNLOAD_INFO + "set completedSize = (select sum(completed_size) from " +
              TABLE_DOWNLOAD_INFO + "where url=? group by url ) where url=?";
          Object[] bindArgs = {compeletedSize, threadId, urlstr};
          Object[] localArgs = {urlstr, urlstr};
          SQLiteDatabase database = dbHelper.getWritableDatabase();
          database.beginTransaction();
          try {
            database.execSQL(sql, bindArgs);
            database.execSQL(localSql, localArgs);
            database.setTransactionSuccessful();
          } catch (SQLException e) {
            e.printStackTrace();
          } finally {
            database.endTransaction();
          }
        }
      }
      /**
       * @param url        ,0     ,1       ,2     
       **/
      public void updateFileStatus(String url) {
        synchronized (file_Lock) {
          String sql = "update " + TABLE_LOCALDOWNLOAD_INFO + " set status = ? where url = ?";
          Object[] bindArgs = {1, url};
          SQLiteDatabase database = dbHelper.getWritableDatabase();
          database.beginTransaction();
          try {
            database.execSQL(sql, bindArgs);
            database.setTransactionSuccessful();
          } catch (SQLException e) {
            e.printStackTrace();
          } finally {
            database.endTransaction();
          }
        }
      }
      /**
       * @return List<FileStatus>
       *           ,         ,            
       **/
      public List<FileStatus> getFileStatus() {
        List<FileStatus> list = new ArrayList<FileStatus>();
        SQLiteDatabase database = dbHelper.getReadableDatabase();
        //String sql = "slect * from " + TABLE_LOCALDOWNLOAD_INFO + ""; //   ,                 
        String sql = "select name, url, status, completedSize, fileSize from " + TABLE_LOCALDOWNLOAD_INFO + "";
        Cursor cursor = database.rawQuery(sql, null);
        while (cursor.moveToNext()) {
          FileStatus fileState = new FileStatus(cursor.getString(0), cursor.getString(1), cursor.getInt(2), cursor.getInt(3), cursor.getInt(4));
          list.add(fileState);
        }
        cursor.close();
        return list;
      }
      /**
       * @param url
       * @param completeSize
       * @param status             
       **/
      public void updateFileDownStatus(int completeSize, int status, String url) {
        synchronized (file_Lock) {
          String sql = "update " + TABLE_LOCALDOWNLOAD_INFO + " set completedSize = ?,status = ? where url = ?";
          SQLiteDatabase database = dbHelper.getWritableDatabase();
          database.beginTransaction();
          try {
            Object[] bindArgs = {completeSize, status, url};
            database.execSQL(sql, bindArgs);
            database.delete(TABLE_DOWNLOAD_INFO, "url = ?", new String[]{url});
            database.setTransactionSuccessful();
          } catch (SQLException e) {
            e.printStackTrace();
          } finally {
            database.endTransaction();
          }
        }
      }
      /**
       * @param url       
       **/
      public String getFileName(String url) {
        String result = "";
        String sql = "select name from " + TABLE_LOCALDOWNLOAD_INFO + " where url = ?";
        SQLiteDatabase database = dbHelper.getReadableDatabase();
        Cursor cursor = database.rawQuery(sql, new String[]{url});
        if (cursor.moveToNext()) {
          result = cursor.getString(0);
        }
        cursor.close();
        return result;
      }
      /**
       *       ,        ,           
       *                      
       *
       * @param url
       */
      public void deleteFile(String url) {
        SQLiteDatabase database = dbHelper.getWritableDatabase();
        database.beginTransaction();
        try {
          database.delete(TABLE_DOWNLOAD_INFO, " url = ?", new String[]{url});
          database.delete(TABLE_LOCALDOWNLOAD_INFO, " url = ?", new String[]{url});
          database.setTransactionSuccessful();
        } catch (Exception e) {
          e.printStackTrace();
        } finally {
          database.endTransaction();
        }
      }
      /**
       *      
       *
       * @close
       */
      public void closeDB() {
        dbHelper.close();
      }
    }
    
    DownloadService 주요 코드
    
    @SuppressLint("HandlerLeak")
    public class DownloadService extends Service
    {
     public IBinder binder = new MyBinder();
     public class MyBinder extends Binder
     {
     public DownloadService getService()
     {
      return DownloadService.this;
     }
     }
     @Override
     public IBinder onBind(Intent intent)
     {
     return binder;
     }
     public static int number = 0;
     //       
     public final String savePath = "/mnt/sdcard/MultiFileDownload/";
     //          
     public static List<FileStatus> list = new ArrayList<FileStatus>();
     public static Map<String, String> localDownList = new HashMap<String, String>();
     //             
     public static Map<String, Downloader> downloaders = new HashMap<String, Downloader>();
     //            
     private Map<String, Integer> completeSizes = new HashMap<String, Integer>();
     //           
     private Map<String, Integer> fileSizes = new HashMap<String, Integer>();
     private Downloader downloader;
     private int threadCount = 5;
     private Dao dao;
     private DownLoadCallback loadCallback;
     
     private FileStatus mFileStatus = null;
     private Handler handler = new Handler()
     {
     @Override
     public void handleMessage(Message msg)
     {
      super.handleMessage(msg);
      if (msg.what == 1)
      {
      String url = (String) msg.obj;
      int length = msg.arg1;
      int completeSize = completeSizes.get(url);
      int fileSize = fileSizes.get(url);
      completeSize += length;
      completeSizes.put(url, completeSize);
      synchronized (list)
      {
       for (int i = 0; i < list.size(); i++)
       {
       FileStatus fileStatus = list.get(i);
       if (fileStatus.getUrl().equals(url))
       {
        if (completeSize == fileStatus.getFileSize())
        {
        System.out.println("-----------    :"+fileStatus.getName()+":"+completeSize+"-----"+fileStatus.getFileSize());
        list.set(i, new FileStatus(fileStatus.getName(), fileStatus.getUrl(), 1, completeSize, fileStatus.getFileSize()));
        dao.updateFileDownStatus(completeSize, 1, url);
        }
        else
        {
        list.set(i, new FileStatus(fileStatus.getName(), fileStatus.getUrl(), 0, completeSize, fileStatus.getFileSize()));
        }
        mFileStatus = list.get(i);
       }
       }
       
       this.postDelayed(new Runnable()
       {
       @Override
       public void run()
       {
        if (loadCallback != null && mFileStatus != null)
        {
        loadCallback.refreshUI(mFileStatus);
        }
       }
       }, 1000);
      }
      
      }
     }
     };
     @Override
     public void onCreate()
     {
     super.onCreate();
     dao = Dao.getInstance(this);
     list = dao.getFileStatus();
     for (FileStatus fileStatus : list)
     {
      localDownList.put(fileStatus.getUrl(), fileStatus.getUrl());
     }
     
     Timer timer = new Timer();
     timer.schedule(new TimerTask()
     {
      @Override
      public void run()
      {
      number++;
      }
     }, 0, 1000);
     }
     public void download(final Button button, final String url, final String name, final Handler mHandler)
     {
     if (dao.isExist(url))
     {
      Toast.makeText(this, "   ,      ", Toast.LENGTH_SHORT).show();
      return;
     }
     final String fileName = name + url.substring(url.lastIndexOf("."));
     new Thread(new Runnable()
     {
      @Override
      public void run()
      {
      downloader = downloaders.get(url);
      if (downloader == null)
      {
       downloader = new Downloader(url, savePath, fileName, threadCount, DownloadService.this, handler);
       downloaders.put(url, downloader);
      }
      if (downloader.isDownloading())
       return;
      
      LoadInfo loadInfo = downloader.getDownloaderInfors();
      
      if(loadInfo != null)
      {
       FileStatus fileStatus = new FileStatus(fileName, url, 0, loadInfo.getComplete(), loadInfo.getFileSize());
       dao.insertFileStatus(fileStatus);
       completeSizes.put(url, loadInfo.getComplete());
       fileSizes.put(url, fileStatus.getFileSize());
       list.add(fileStatus);
       localDownList.put(url, url);
       downloader.download();
       Message msg = new Message();
       msg.what = 1;
       msg.obj = button;
       mHandler.sendMessage(msg);
      }
      else
      {
       Message msg = new Message();
       msg.what = 2;
       msg.obj = button;
       mHandler.sendMessage(msg);
      }
      }
     }).start();
     }
     
     //    
     public void Pause(Downloader downloader)
     {
     downloader.pause();
     }
     
     //    
     public void reDownload(final Button button, final String url, final String name, final Handler mHandler)
     {
     new Thread(new Runnable()
     {
      @Override
      public void run()
      {
      String fileName = dao.getFileName(url);
      
      downloader = downloaders.get(url);
      if (downloader == null)
      {
       downloader = new Downloader(url, savePath, fileName, threadCount, DownloadService.this, handler);
       downloaders.put(url, downloader);
      }
      if (downloader.isDownloading())
       return;
      
      LoadInfo loadInfo = downloader.getDownloaderInfors();
      
      if(loadInfo != null && !fileName.equals(""))
      {
       if(!completeSizes.containsKey(url))
       {
       completeSizes.put(url, loadInfo.getComplete());
       }
       if(!fileSizes.containsKey(url))
       {
       fileSizes.put(url, loadInfo.getFileSize());
       }
       downloader.download();
       Message msg = new Message();
       msg.what = 1;
       msg.obj = button;
       mHandler.sendMessage(msg);
      }
      else
      {
       Message msg = new Message();
       msg.what = 2;
       msg.obj = button;
       mHandler.sendMessage(msg);
      }
      }
     }).start();
     }
     
     public void delete(final String url)
     {
     Downloader down = downloaders.get(url);
     if(down != null)
     {
      down.pause();
     }
     
     handler.postDelayed(new Runnable()
     {
      @Override
      public void run()
      {
      dao.deleteFile(url);
      
      for (int i = 0; i < list.size(); i++)
      {
       FileStatus fileStatus = list.get(i);
       if (fileStatus.getUrl().equals(url))
       {
       list.remove(i);
       }
      }
      
      localDownList.remove(url);
      downloaders.remove(url);
      completeSizes.remove(url);
      fileSizes.remove(url);
      
      if(loadCallback != null)
      {
       loadCallback.deleteFile(url);
      }
      }
     }, 1000);
     }
     public interface DownLoadCallback
     {
     public void refreshUI(FileStatus fileStatus);
     
     public void deleteFile(String url);
     }
     public void setLoadCallback(DownLoadCallback loadCallback)
     {
     this.loadCallback = loadCallback;
     }
    }
    
    다운로드 도구 클래스 DownloadUtil
    
    /**
     * Created by ShanCanCan on 2017/3/7 0007.
     */
    public class DownLoadUtil {
      /**
       *        
       * 1、      
       * 2、    ,       httpurlconnection
       */
      private String downPath;//     
      private String savePath;//     
      private String fileName;//     
      private int threadCount;//    
      private Handler mHandler;
      private Dao dao;
      private Context context;
      private int fileSize;//     
      private int range;
      private List<DownLoadInfo> infos;//           
      private int state = INIT;
      private static final int INIT = 1;//          :     ,      ,    
      private static final int DOWNLOADING = 2;
      private static final int PAUSE = 3;
      /**
       *     ,  dao   
       *
       * @param downPath
       * @param savePath
       * @param fileName
       * @param threadCount
       * @param context
       * @param mHandler
       */
      public DownLoadUtil(String downPath, String savePath, String fileName, int threadCount, Handler mHandler, Context context) {
        this.downPath = downPath;
        this.savePath = savePath;
        this.fileName = fileName;
        this.threadCount = threadCount;
        this.mHandler = mHandler;
        this.context = context;
        dao = Dao.getInstance(context);
      }
      /**
       *     PAUSE
       **/
      public boolean isPause() {
        return state == PAUSE;
      }
      /**
       *     DOWNLOADING
       */
      public boolean isDownloading() {
        return state == DOWNLOADING;
      }
      /**
       * @param url           ,  dao                  
       */
      private boolean isFirst(String url) {
        return dao.isFirstDownload(url);
      }
      /**
       *         
       */
      public LoadItemInfo getDownloadInfos() {
        if (isFirst(downPath)) {
          if (initFirst()) {//          ,      ,1.          2.    ,       
            range = this.fileSize / this.threadCount;
            infos = new ArrayList<DownLoadInfo>();
            //           ,     ?  RandomAccessFile。   DownLoadInfo  RandomAccessFile      
            for (int i = 0; i < this.threadCount - 1; i++) {
              DownLoadInfo info = new DownLoadInfo(i, i * range, (i + 1) * range - 1, 0, downPath);
              infos.add(info);
            }
            DownLoadInfo info = new DownLoadInfo(this.threadCount - 1, (this.threadCount - 1) * range, this.fileSize, 0, downPath);
            infos.add(info);
            dao.saveInfos(infos, this.context);
            //(String urlDownload, int completePercent, int fileSize)
            LoadItemInfo loadInfo = new LoadItemInfo(this.downPath, 0, this.fileSize);
            return loadInfo;
          } else {
            return null;
          }
        } else {
          //       ,        ?         
          infos = dao.getInfos(this.downPath);
          if (infos != null && infos.size() > 0) {
            int size = 0;
            int completeSize = 0;
            for (DownLoadInfo info : infos) {
              completeSize += info.getCompletedSize();
              size += info.getEndPosition() - info.getStartPosition() + this.threadCount - 1;
            }
            LoadItemInfo loadInfo = new LoadItemInfo(this.downPath, completeSize, size);
            return loadInfo;
          } else {
            return null;
          }
        }
      }
      //     
      public void pause() {
        state = PAUSE;
      }
      //       ,        init     
      public void reset() {
        state = INIT;
      }
      /**
       *    ,RandomAccessFile      , DataInputStream DataOutputStream    ,           ,
       *       getFilePointer( ),        seek( ),         length( )、skipBytes()       。
       *   ,                 ("r"),       ("rw")        ( C fopen( )    )。        。
       */
      private boolean initFirst() {
        boolean result = true;
        HttpURLConnection conn = null;
        RandomAccessFile randomFile = null;
        URL url = null;
        try {
          url = new URL(downPath);
          conn = (HttpURLConnection) url.openConnection();
          conn.setConnectTimeout(5 * 1000);
          conn.setRequestMethod("GET");
          //   http      200  206      
          if (conn.getResponseCode() == 200 || conn.getResponseCode() == 206) //   (206),                GET  
          {
            fileSize = conn.getContentLength();//        
            if (fileSize <= 0) {
              //("    ,        ");
              return false;
            }
            File dir = new File(savePath);
            //          ,   
            if (!dir.exists()) {
              if (dir.mkdirs()) {
                //("mkdirs success.");
              }
            }
            File file = new File(this.savePath, this.fileName);
            randomFile = new RandomAccessFile(file, "rwd");
            randomFile.setLength(fileSize);//          
            randomFile.close();
            conn.disconnect();
          }
        } catch (Exception e) {
          e.printStackTrace();
          result = false;
        } finally {
          if (randomFile != null) {
            try {
              randomFile.close();
            } catch (IOException e) {
              e.printStackTrace();
            }
          }
          if (conn != null) {
            conn.disconnect();
          }
        }
        return result;
      }
      /**
       *                       
       */
      public void downLoad() {
        if (infos != null) {
          if (state == DOWNLOADING) {
            return;
          }
          state = DOWNLOADING;//           
          for (DownLoadInfo info : infos) {//           ?                     RandomAccessFile  
            new DownLoadThread(info.getThreadId(), info.getStartPosition(), info.getEndPosition(), info.getCompletedSize(), info.getUrl(), this.context).start();
          }
        }
      }
      /**
       *             ,       
       */
      public class DownLoadThread extends Thread {
        private int threadId;
        private int startPostion;
        private int endPostion;
        private int compeletedSize;
        private String url;
        private Context context;
        public static final int PROGRESS = 1;
        public DownLoadThread(int threadId, int startPostion, int endPostion, int compeletedSize, String url, Context context) {//    ,       
          this.threadId = threadId;
          this.startPostion = startPostion;
          this.endPostion = endPostion;
          this.compeletedSize = compeletedSize;
          this.url = url;
          this.context = context;
        }
        //    
        @Override
        public void run() {
          HttpURLConnection conn = null;
          RandomAccessFile randomAccessFile = null;
          InputStream inStream = null;
          File file = new File(savePath, fileName);
          URL url = null;
          try {
            url = new URL(this.url);
            conn = (HttpURLConnection) url.openConnection();
            constructConnection(conn);
            if (conn.getResponseCode() == 200 || conn.getResponseCode() == 206) {
              randomAccessFile = new RandomAccessFile(file, "rwd");
              randomAccessFile.seek(this.startPostion + this.compeletedSize);//RandomAccessFile    ,       
              inStream = conn.getInputStream();
              byte buffer[] = new byte[4096];//  4096    ?     ,         apk     4096,   
              int length = 0;
              while ((length = inStream.read(buffer, 0, buffer.length)) != -1) {
                randomAccessFile.write(buffer, 0, length);
                compeletedSize += length;
                //            
                dao.updataInfos(threadId, compeletedSize, this.url, this.context);
                //              ,        
                Message message = Message.obtain();
                message.what = PROGRESS;
                message.obj = this.url;
                message.arg1 = length;
                mHandler.sendMessage(message);//  DownloadService    
                if (state == PAUSE) {
                  //("-----pause-----");
                  return;
                }
              }
              // ("------------  :" + this.threadId + "    ");
            }
          } catch (IOException e) {
            e.printStackTrace();
            //("-----    -----");             ,             
          } finally {//        ,          ,    
            try {
              if (inStream != null) {
                inStream.close();
              }
              if (randomAccessFile != null) {
                randomAccessFile.close();
              }
              if (conn != null) {
                conn.disconnect();
              }
            } catch (IOException e) {
              e.printStackTrace();
            }
          }
        }
        /**
         *                     
         *
         * @param conn
         */
        private void constructConnection(HttpURLConnection conn) throws IOException {
          conn.setConnectTimeout(5 * 1000);//       5 
          conn.setRequestMethod("GET");// GET    ,     post       conn.setDoOutput(true); conn.setDoInput(true);
          conn.setRequestProperty(
              "Accept",
              "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
          conn.setRequestProperty("Accept-Language", "zh-CN");
          conn.setRequestProperty("Referer", this.url);
          conn.setRequestProperty("Charset", "UTF-8");
          int startPositionNew = this.startPostion + this.compeletedSize;
          //            
          conn.setRequestProperty("Range", "bytes=" + startPositionNew + "-" + this.endPostion);
          conn.setRequestProperty(
              "User-Agent",
              "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
          conn.setRequestProperty("Connection", "Keep-Alive");
          conn.connect();
        }
      }
    }
    
    Github 주소:https://github.com/Shanlovana/DownLoadFiles/
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기