|  |  | @ -40,7 +40,7 @@ import java.util.concurrent.Executors; | 
			
		
	
		
		
			
				
					
					|  |  |  |  */ |  |  |  |  */ | 
			
		
	
		
		
			
				
					
					|  |  |  | public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>> |  |  |  | public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>> | 
			
		
	
		
		
			
				
					
					|  |  |  |     implements Runnable, IUtil { |  |  |  |     implements Runnable, IUtil { | 
			
		
	
		
		
			
				
					
					|  |  |  |   private final String TAG = "Downloader"; |  |  |  |   private final String TAG = "AbsFileer"; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   protected IEventListener mListener; |  |  |  |   protected IEventListener mListener; | 
			
		
	
		
		
			
				
					
					|  |  |  |   protected TASK_ENTITY mTaskEntity; |  |  |  |   protected TASK_ENTITY mTaskEntity; | 
			
		
	
		
		
			
				
					
					|  |  |  |   protected ENTITY mEntity; |  |  |  |   protected ENTITY mEntity; | 
			
		
	
	
		
		
			
				
					|  |  | @ -50,7 +50,12 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte | 
			
		
	
		
		
			
				
					
					|  |  |  |   protected boolean isNewTask = true; |  |  |  |   protected boolean isNewTask = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |   protected StateConstance mConstance; |  |  |  |   protected StateConstance mConstance; | 
			
		
	
		
		
			
				
					
					|  |  |  |   private ExecutorService mFixedThreadPool; |  |  |  |   private ExecutorService mFixedThreadPool; | 
			
		
	
		
		
			
				
					
					|  |  |  |   private int mThreadNum, mRealThreadNum; |  |  |  |   //总线程数
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   private int mTotalThreadNum; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   //启动线程数
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   private int mStartThreadNum; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   //已完成的线程数
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   private int mCompleteThreadNum; | 
			
		
	
		
		
			
				
					
					|  |  |  |   private SparseArray<AbsThreadTask> mTask = new SparseArray<>(); |  |  |  |   private SparseArray<AbsThreadTask> mTask = new SparseArray<>(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   /** |  |  |  |   /** | 
			
		
	
	
		
		
			
				
					|  |  | @ -72,7 +77,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   @Override public void setMaxSpeed(double maxSpeed) { |  |  |  |   @Override public void setMaxSpeed(double maxSpeed) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     for (int i = 0; i < mThreadNum; i++) { |  |  |  |     for (int i = 0; i < mTotalThreadNum; i++) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       AbsThreadTask task = mTask.get(i); |  |  |  |       AbsThreadTask task = mTask.get(i); | 
			
		
	
		
		
			
				
					
					|  |  |  |       if (task != null) { |  |  |  |       if (task != null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         task.setMaxSpeed(maxSpeed); |  |  |  |         task.setMaxSpeed(maxSpeed); | 
			
		
	
	
		
		
			
				
					|  |  | @ -101,12 +106,13 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte | 
			
		
	
		
		
			
				
					
					|  |  |  |       ((IDownloadListener) mListener).onPostPre(mEntity.getFileSize()); |  |  |  |       ((IDownloadListener) mListener).onPostPre(mEntity.getFileSize()); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (!mTaskEntity.isSupportBP) { |  |  |  |     if (!mTaskEntity.isSupportBP) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       mThreadNum = 1; |  |  |  |       mTotalThreadNum = 1; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       mConstance.THREAD_NUM = mThreadNum; |  |  |  |       mStartThreadNum = 1; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       mConstance.THREAD_NUM = mTotalThreadNum; | 
			
		
	
		
		
			
				
					
					|  |  |  |       handleNoSupportBP(); |  |  |  |       handleNoSupportBP(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } else { |  |  |  |     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |       mThreadNum = isNewTask ? (getNewTaskThreadNum()) : mRealThreadNum; |  |  |  |       mTotalThreadNum = isNewTask ? (getNewTaskThreadNum()) : mStartThreadNum + mCompleteThreadNum; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       mConstance.THREAD_NUM = mThreadNum; |  |  |  |       mConstance.THREAD_NUM = mTotalThreadNum; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       handleBreakpoint(); |  |  |  |       handleBreakpoint(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     startTimer(); |  |  |  |     startTimer(); | 
			
		
	
	
		
		
			
				
					|  |  | @ -116,8 +122,8 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte | 
			
		
	
		
		
			
				
					
					|  |  |  |    * 设置新任务的最大线程数 |  |  |  |    * 设置新任务的最大线程数 | 
			
		
	
		
		
			
				
					
					|  |  |  |    */ |  |  |  |    */ | 
			
		
	
		
		
			
				
					
					|  |  |  |   protected int getNewTaskThreadNum() { |  |  |  |   protected int getNewTaskThreadNum() { | 
			
		
	
		
		
			
				
					
					|  |  |  |     return mEntity.getFileSize() <= SUB_LEN || mTaskEntity.requestType == AbsTaskEntity.D_FTP_DIR ? 1 |  |  |  |     return mEntity.getFileSize() <= SUB_LEN || mTaskEntity.requestType == AbsTaskEntity.D_FTP_DIR | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         : AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum(); |  |  |  |         ? 1 : AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum(); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   /** |  |  |  |   /** | 
			
		
	
	
		
		
			
				
					|  |  | @ -169,7 +175,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (mFixedThreadPool != null) { |  |  |  |     if (mFixedThreadPool != null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       mFixedThreadPool.shutdown(); |  |  |  |       mFixedThreadPool.shutdown(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     for (int i = 0; i < mThreadNum; i++) { |  |  |  |     for (int i = 0; i < mStartThreadNum; i++) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       AbsThreadTask task = mTask.get(i); |  |  |  |       AbsThreadTask task = mTask.get(i); | 
			
		
	
		
		
			
				
					
					|  |  |  |       if (task != null) { |  |  |  |       if (task != null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         task.cancel(); |  |  |  |         task.cancel(); | 
			
		
	
	
		
		
			
				
					|  |  | @ -190,7 +196,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (mFixedThreadPool != null) { |  |  |  |     if (mFixedThreadPool != null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       mFixedThreadPool.shutdown(); |  |  |  |       mFixedThreadPool.shutdown(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     for (int i = 0; i < mThreadNum; i++) { |  |  |  |     for (int i = 0; i < mStartThreadNum; i++) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       AbsThreadTask task = mTask.get(i); |  |  |  |       AbsThreadTask task = mTask.get(i); | 
			
		
	
		
		
			
				
					
					|  |  |  |       if (task != null) { |  |  |  |       if (task != null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         task.stop(); |  |  |  |         task.stop(); | 
			
		
	
	
		
		
			
				
					|  |  | @ -230,6 +236,8 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte | 
			
		
	
		
		
			
				
					
					|  |  |  |    * 检查记录文件,如果是新任务返回{@code true},否则返回{@code false} |  |  |  |    * 检查记录文件,如果是新任务返回{@code true},否则返回{@code false} | 
			
		
	
		
		
			
				
					
					|  |  |  |    */ |  |  |  |    */ | 
			
		
	
		
		
			
				
					
					|  |  |  |   protected boolean checkConfigFile() { |  |  |  |   protected boolean checkConfigFile() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     mStartThreadNum = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     mCompleteThreadNum = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |     Properties pro = CommonUtil.loadConfig(mConfigFile); |  |  |  |     Properties pro = CommonUtil.loadConfig(mConfigFile); | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (pro.isEmpty()) { |  |  |  |     if (pro.isEmpty()) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       return true; |  |  |  |       return true; | 
			
		
	
	
		
		
			
				
					|  |  | @ -237,15 +245,18 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte | 
			
		
	
		
		
			
				
					
					|  |  |  |     Set<Object> keys = pro.keySet(); |  |  |  |     Set<Object> keys = pro.keySet(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     int num = 0; |  |  |  |     int num = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |     for (Object key : keys) { |  |  |  |     for (Object key : keys) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       if (String.valueOf(key).contains("_record_")) { |  |  |  |       String str = String.valueOf(key); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       if (str.contains("_record_")) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         num++; |  |  |  |         num++; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } else if (str.contains("_state_")) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         mCompleteThreadNum++; | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (num == 0) { |  |  |  |     if (num == 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       return true; |  |  |  |       return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     mRealThreadNum = num; |  |  |  |     mStartThreadNum = num; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     for (int i = 0; i < mRealThreadNum; i++) { |  |  |  |     for (int i = 0; i < mStartThreadNum; i++) { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       if (pro.getProperty(mTempFile.getName() + "_record_" + i) == null) { |  |  |  |       if (pro.getProperty(mTempFile.getName() + "_record_" + i) == null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         Object state = pro.getProperty(mTempFile.getName() + "_state_" + i); |  |  |  |         Object state = pro.getProperty(mTempFile.getName() + "_state_" + i); | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (state != null && Integer.parseInt(state + "") == 1) { |  |  |  |         if (state != null && Integer.parseInt(state + "") == 1) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -264,8 +275,8 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte | 
			
		
	
		
		
			
				
					
					|  |  |  |    */ |  |  |  |    */ | 
			
		
	
		
		
			
				
					
					|  |  |  |   private boolean resumeRecordLocation(int i, long startL, long endL) { |  |  |  |   private boolean resumeRecordLocation(int i, long startL, long endL) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     mConstance.CURRENT_LOCATION += endL - startL; |  |  |  |     mConstance.CURRENT_LOCATION += endL - startL; | 
			
		
	
		
		
			
				
					
					|  |  |  |     ALog.d(TAG, "++++++++++ 线程_" + i + "_已经下载完成 ++++++++++"); |  |  |  |     ALog.d(TAG, "任务【" + mTaskEntity.getEntity().getFileName() + "】线程__" + i + "__已完成"); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     mConstance.COMPLETE_THREAD_NUM++; |  |  |  |     mConstance.COMPLETE_THREAD_NUM = mCompleteThreadNum; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     mConstance.STOP_NUM++; |  |  |  |     mConstance.STOP_NUM++; | 
			
		
	
		
		
			
				
					
					|  |  |  |     mConstance.CANCEL_NUM++; |  |  |  |     mConstance.CANCEL_NUM++; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (mConstance.isComplete()) { |  |  |  |     if (mConstance.isComplete()) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -307,16 +318,16 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte | 
			
		
	
		
		
			
				
					
					|  |  |  |   private void handleBreakpoint() { |  |  |  |   private void handleBreakpoint() { | 
			
		
	
		
		
			
				
					
					|  |  |  |     long fileLength = mEntity.getFileSize(); |  |  |  |     long fileLength = mEntity.getFileSize(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     Properties pro = CommonUtil.loadConfig(mConfigFile); |  |  |  |     Properties pro = CommonUtil.loadConfig(mConfigFile); | 
			
		
	
		
		
			
				
					
					|  |  |  |     long blockSize = fileLength / mThreadNum; |  |  |  |     long blockSize = fileLength / mTotalThreadNum; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     int[] recordL = new int[mThreadNum]; |  |  |  |     int[] recordL = new int[mTotalThreadNum]; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     for (int i = 0; i < mThreadNum; i++) { |  |  |  |     for (int i = 0; i < mTotalThreadNum; i++) { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       recordL[i] = -1; |  |  |  |       recordL[i] = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     int rl = 0; |  |  |  |     int rl = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (isNewTask) { |  |  |  |     if (isNewTask) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       handleNewTask(); |  |  |  |       handleNewTask(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     for (int i = 0; i < mThreadNum; i++) { |  |  |  |     for (int i = 0; i < mTotalThreadNum; i++) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       long startL = i * blockSize, endL = (i + 1) * blockSize; |  |  |  |       long startL = i * blockSize, endL = (i + 1) * blockSize; | 
			
		
	
		
		
			
				
					
					|  |  |  |       Object state = pro.getProperty(mTempFile.getName() + "_state_" + i); |  |  |  |       Object state = pro.getProperty(mTempFile.getName() + "_state_" + i); | 
			
		
	
		
		
			
				
					
					|  |  |  |       if (state != null && Integer.parseInt(state + "") == 1) {  //该线程已经完成
 |  |  |  |       if (state != null && Integer.parseInt(state + "") == 1) {  //该线程已经完成
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -339,7 +350,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte | 
			
		
	
		
		
			
				
					
					|  |  |  |         recordL[rl] = i; |  |  |  |         recordL[rl] = i; | 
			
		
	
		
		
			
				
					
					|  |  |  |         rl++; |  |  |  |         rl++; | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |       if (i == (mThreadNum - 1)) { |  |  |  |       if (i == (mTotalThreadNum - 1)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         //最后一个线程的结束位置即为文件的总长度
 |  |  |  |         //最后一个线程的结束位置即为文件的总长度
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         endL = fileLength; |  |  |  |         endL = fileLength; | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |