diff --git a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java index 1a0eb578..f94b69c2 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java +++ b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java @@ -25,6 +25,7 @@ import android.os.Build; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; +import android.text.TextUtils; import android.widget.PopupWindow; import com.arialyy.aria.core.command.ICmd; import com.arialyy.aria.core.common.QueueMod; @@ -293,39 +294,10 @@ import org.xml.sax.SAXException; return receiver; } - /** - * 不允许在"onDestroy"、"finish"、"onStop"这三个方法中添加注册器 - */ private AbsReceiver checkTarget(String key, AbsReceiver receiver, Object obj, boolean needRmReceiver) { - StackTraceElement[] stack = Thread.currentThread().getStackTrace(); - int i = 0; - for (StackTraceElement e : stack) { - String name = e.getClassName(); - if (!name.equals(AriaManager.class.getName())) { - i++; - } else { - break; - } - } - i += 4; - String methodName = stack[i].getMethodName(); - boolean isDestroyed = - methodName.equals("onDestroy") || methodName.equals("finish") || methodName.equals( - "onStop"); - - if (isDestroyed) { - ALog.e(TAG, - "请不要在Activity或Fragment的onDestroy、finish、onStop等方法中注册Aria,Aria的unRegister会在Activity页面销毁时自动执行"); - } - - if (obj instanceof Activity && isDestroyed) { - return receiver; - } else if (obj instanceof Fragment && isDestroyed) { - return receiver; - } receiver.targetName = obj.getClass().getName(); - receiver.obj = obj; + AbsReceiver.OBJ_MAP.put(receiver.getKey(), obj); receiver.needRmListener = needRmReceiver; mReceivers.put(key, receiver); return receiver; @@ -430,29 +402,16 @@ import org.xml.sax.SAXException; /** * 移除指定对象的receiver */ - public void removeReceiver(Object obj) { - if (obj == null) return; - String clsName = obj.getClass().getName(); - for (Iterator> iter = mReceivers.entrySet().iterator(); - iter.hasNext(); ) { - Map.Entry entry = iter.next(); - String key = entry.getKey(); - if (key.contains(clsName)) { - iter.remove(); - } + public void removeReceiver(String targetName) { + if (TextUtils.isEmpty(targetName)) { + ALog.e(TAG, "target name null"); + return; } - } - - /** - * Aria注册对象被销毁时调用 - */ - void destroySchedulerListener(Object obj) { - String clsName = obj.getClass().getName(); for (Iterator> iter = mReceivers.entrySet().iterator(); iter.hasNext(); ) { Map.Entry entry = iter.next(); String key = entry.getKey(); - if (key.contains(clsName)) { + if (key.contains(targetName)) { AbsReceiver receiver = mReceivers.get(key); if (receiver != null) { receiver.unRegisterListener(); @@ -493,7 +452,7 @@ import org.xml.sax.SAXException; } @Override public void onActivityDestroyed(Activity activity) { - destroySchedulerListener(activity); + removeReceiver(activity.getClass().getName()); // TODO: 2018/4/11 维护一个activity堆栈,应用被kill,activity会回调onDestroy方法,需要考虑server后台情况 } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/WidgetLiftManager.java b/Aria/src/main/java/com/arialyy/aria/core/WidgetLiftManager.java index d2dacfd9..32f970b8 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/WidgetLiftManager.java +++ b/Aria/src/main/java/com/arialyy/aria/core/WidgetLiftManager.java @@ -80,7 +80,7 @@ final class WidgetLiftManager { private PopupWindow.OnDismissListener createPopupWindowListener(final PopupWindow popupWindow) { return new PopupWindow.OnDismissListener() { @Override public void onDismiss() { - AriaManager.getInstance(AriaManager.APP).destroySchedulerListener(popupWindow); + AriaManager.getInstance(AriaManager.APP).removeReceiver(popupWindow.getClass().getName()); } }; } @@ -120,7 +120,8 @@ final class WidgetLiftManager { return new Dialog.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { - AriaManager.getInstance(AriaManager.APP).destroySchedulerListener(dialog); + AriaManager.getInstance(AriaManager.APP) + .destroySchedulerListener(dialog.getClass().getName()); } }; } @@ -132,7 +133,8 @@ final class WidgetLiftManager { return new Dialog.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { - AriaManager.getInstance(AriaManager.APP).destroySchedulerListener(dialog); + AriaManager.getInstance(AriaManager.APP) + .destroySchedulerListener(dialog.getClass().getName()); } }; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java index 8a8e64d0..909e564c 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java @@ -18,6 +18,7 @@ package com.arialyy.aria.core.download; import android.support.annotation.CheckResult; import android.support.annotation.NonNull; import android.text.TextUtils; +import android.util.Log; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.command.ICmd; import com.arialyy.aria.core.command.normal.CancelAllCmd; @@ -27,6 +28,7 @@ import com.arialyy.aria.core.download.wrapper.DGEWrapper; import com.arialyy.aria.core.inf.AbsEntity; import com.arialyy.aria.core.inf.AbsReceiver; import com.arialyy.aria.core.inf.AbsTarget; +import com.arialyy.aria.core.inf.ReceiverType; import com.arialyy.aria.core.manager.TEManager; import com.arialyy.aria.core.scheduler.DownloadGroupSchedulers; import com.arialyy.aria.core.scheduler.DownloadSchedulers; @@ -229,15 +231,23 @@ public class DownloadReceiver extends AbsReceiver { * 将当前类注册到Aria */ public void register() { - String className = obj.getClass().getName(); + if (TextUtils.isEmpty(targetName)) { + ALog.e(TAG, "download register target null"); + return; + } + Object obj = OBJ_MAP.get(getKey()); + if (obj == null) { + ALog.e(TAG, String.format("【%s】观察者为空", targetName)); + return; + } Set dCounter = ProxyHelper.getInstance().downloadCounter; Set dgCounter = ProxyHelper.getInstance().downloadGroupCounter; Set dgsCounter = ProxyHelper.getInstance().downloadGroupSubCounter; - if (dCounter != null && dCounter.contains(className)) { + if (dCounter != null && dCounter.contains(targetName)) { DownloadSchedulers.getInstance().register(obj); } - if ((dgCounter != null && dgCounter.contains(className)) || (dgsCounter != null - && dgsCounter.contains(className))) { + if ((dgCounter != null && dgCounter.contains(targetName)) || (dgsCounter != null + && dgsCounter.contains(targetName))) { DownloadGroupSchedulers.getInstance().register(obj); } } @@ -251,25 +261,37 @@ public class DownloadReceiver extends AbsReceiver { if (needRmListener) { unRegisterListener(); } - AriaManager.getInstance(AriaManager.APP).removeReceiver(obj); + AriaManager.getInstance(AriaManager.APP).removeReceiver(targetName); + } + + @Override protected String getType() { + return ReceiverType.DOWNLOAD; } @Override public void unRegisterListener() { - String className = obj.getClass().getName(); + if (TextUtils.isEmpty(targetName)) { + ALog.e(TAG, "download unRegisterListener target null"); + return; + } + Object obj = OBJ_MAP.get(getKey()); + if (obj == null) { + ALog.e(TAG, String.format("【%s】观察者为空", targetName)); + return; + } Set dCounter = ProxyHelper.getInstance().downloadCounter; Set dgCounter = ProxyHelper.getInstance().downloadGroupCounter; Set dgsCounter = ProxyHelper.getInstance().downloadGroupSubCounter; - if (dCounter != null && dCounter.contains(className)) { + if (dCounter != null && dCounter.contains(targetName)) { DownloadSchedulers.getInstance().unRegister(obj); } - if (dgCounter != null && dgCounter.contains(className) || (dgsCounter != null - && dgsCounter.contains(className))) { + if (dgCounter != null && dgCounter.contains(targetName) || (dgsCounter != null + && dgsCounter.contains(targetName))) { DownloadGroupSchedulers.getInstance().unRegister(obj); } } @Override public void destroy() { - targetName = null; + removeObj(); } /** @@ -338,8 +360,10 @@ public class DownloadReceiver extends AbsReceiver { /** * 下载任务是否存在 + * + * @return {@code true}存在,{@code false} 不存在 */ - @Override public boolean taskExists(String downloadUrl) { + public boolean taskExists(String downloadUrl) { return DownloadEntity.findFirst(DownloadEntity.class, "url=?", downloadUrl) != null; } @@ -362,7 +386,7 @@ public class DownloadReceiver extends AbsReceiver { * 获取未完成的普通任务列表{@link #getAllNotCompletTask()} * 获取已经完成的普通任务列表{@link #getAllCompleteTask()} */ - @Override public List getTaskList() { + public List getTaskList() { return DownloadEntity.findDatas(DownloadEntity.class, "isGroupChild=? and downloadPath!=''", "false"); } @@ -419,7 +443,7 @@ public class DownloadReceiver extends AbsReceiver { /** * 停止所有正在下载的任务,并清空等待队列。 */ - @Override public void stopAllTask() { + public void stopAllTask() { AriaManager.getInstance(AriaManager.APP) .setCmd(NormalCmdFactory.getInstance() .createCmd(targetName, new DownloadTaskEntity(), NormalCmdFactory.TASK_STOP_ALL, @@ -446,7 +470,7 @@ public class DownloadReceiver extends AbsReceiver { * @param removeFile {@code true} 删除已经下载完成的任务,不仅删除下载记录,还会删除已经下载完成的文件,{@code false} * 如果文件已经下载完成,只删除下载记录 */ - @Override public void removeAllTask(boolean removeFile) { + public void removeAllTask(boolean removeFile) { final AriaManager ariaManager = AriaManager.getInstance(AriaManager.APP); CancelAllCmd cancelCmd = (CancelAllCmd) CommonUtil.createNormalCmd(targetName, new DownloadTaskEntity(), diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsReceiver.java index b1c6fa4f..dc1c2d04 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsReceiver.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsReceiver.java @@ -16,19 +16,76 @@ package com.arialyy.aria.core.inf; +import com.arialyy.aria.core.queue.DownloadGroupTaskQueue; +import com.arialyy.aria.core.queue.DownloadTaskQueue; +import com.arialyy.aria.core.queue.UploadTaskQueue; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + /** * Created by AriaL on 2017/6/27. + * 接收器 */ +public abstract class AbsReceiver implements IReceiver { + /** + * 观察者对象map + * key 由 {@link #getKey(String, IReceiver)}指定 + */ + public static final Map OBJ_MAP = new ConcurrentHashMap<>(); -public abstract class AbsReceiver implements IReceiver { public String targetName; - public Object obj; /** * 当dialog、dialogFragment、popupwindow已经被设置了关闭监听时,需要手动移除receiver */ public boolean needRmListener = false; - public void unRegisterListener(){ + /** + * 创建观察者对象map的key,生成规则: + * {@link #targetName}_{@code download}{@code upload}_{@link #hashCode()} + * + * @param type {@link ReceiverType} + * @param receiver 当前接收器 + * @return 返回key + */ + public static String getKey(@ReceiverType String type, IReceiver receiver) { + return String.format("%s_%s_%s", receiver.getTargetName(), type, receiver.hashCode()); + } + + @Override public String getTargetName() { + return targetName; + } + + /** + * 获取当前Receiver的key + */ + @Override public String getKey() { + return getKey(getType(), this); + } + /** + * 移除观察者对象 + */ + protected void removeObj() { + for (Iterator> iter = OBJ_MAP.entrySet().iterator(); + iter.hasNext(); ) { + Map.Entry entry = iter.next(); + String key = entry.getKey(); + if (key.equals(getKey())) { + iter.remove(); + } + } } + + /** + * 设置类型 + * + * @return {@link ReceiverType} + */ + protected abstract @ReceiverType String getType(); + + /** + * 移除{@link DownloadTaskQueue}、{@link DownloadGroupTaskQueue}、{@link UploadTaskQueue}中注册的观察者 + */ + public abstract void unRegisterListener(); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/IReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IReceiver.java index ce00506c..639dc24d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/IReceiver.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IReceiver.java @@ -15,42 +15,32 @@ */ package com.arialyy.aria.core.inf; -import java.util.List; - /** * Created by lyy on 2017/2/6. */ -public interface IReceiver { +public interface IReceiver { /** * Receiver 销毁 */ void destroy(); - /** - * 移除观察者 + * 注册 */ - void unRegister(); + void register(); /** - * 停止所有任务 - */ - void stopAllTask(); - - /** - * 删除所有任务 + * 移除观察者 */ - void removeAllTask(boolean removeFile); + void unRegister(); /** - * 任务是否存在 - * - * @param key 下载时为下载路径,上传时为文件路径 + * 观察者对象的类完整名称 */ - boolean taskExists(String key); + String getTargetName(); /** - * 获取任务列表 + * 获取当前Receiver的key */ - List getTaskList(); + String getKey(); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/ReceiverType.java b/Aria/src/main/java/com/arialyy/aria/core/inf/ReceiverType.java new file mode 100644 index 00000000..f18d7dd3 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/ReceiverType.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.arialyy.aria.core.inf; + +import android.support.annotation.StringDef; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * {@link AbsReceiver}类型 + */ +@StringDef({ + ReceiverType.DOWNLOAD, + ReceiverType.UPLOAD, +}) +@Retention(RetentionPolicy.SOURCE) +public @interface ReceiverType { + String DOWNLOAD = "download"; + String UPLOAD = "upload"; +} \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java index d42c80fb..aa0d63f6 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java @@ -23,8 +23,10 @@ import com.arialyy.aria.core.command.ICmd; import com.arialyy.aria.core.command.normal.NormalCmdFactory; import com.arialyy.aria.core.common.ProxyHelper; import com.arialyy.aria.core.inf.AbsReceiver; +import com.arialyy.aria.core.inf.ReceiverType; import com.arialyy.aria.core.scheduler.UploadSchedulers; import com.arialyy.aria.orm.DbEntity; +import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.CheckUtil; import com.arialyy.aria.util.CommonUtil; import java.util.List; @@ -34,7 +36,7 @@ import java.util.Set; * Created by lyy on 2017/2/6. * 上传功能接收器 */ -public class UploadReceiver extends AbsReceiver { +public class UploadReceiver extends AbsReceiver { private static final String TAG = "UploadReceiver"; /** @@ -71,9 +73,11 @@ public class UploadReceiver extends AbsReceiver { } /** - * 下载任务是否存在 + * 上传任务是否存在 + * + * @return {@code true}存在,{@code false} 不存在 */ - @Override public boolean taskExists(String filePath) { + public boolean taskExists(String filePath) { return DbEntity.findFirst(UploadEntity.class, "filePath=?", filePath) != null; } @@ -82,7 +86,7 @@ public class UploadReceiver extends AbsReceiver { * 获取未完成的普通任务列表{@link #getAllNotCompletTask()} * 获取已经完成的普通任务列表{@link #getAllCompleteTask()} */ - @Override public List getTaskList() { + public List getTaskList() { return DbEntity.findAllData(UploadEntity.class); } @@ -102,7 +106,10 @@ public class UploadReceiver extends AbsReceiver { "isGroupChild=? and isComplete=?", "false", "true"); } - @Override public void stopAllTask() { + /** + * 停止所有正在下载的任务,并清空等待队列。 + */ + public void stopAllTask() { AriaManager.getInstance(AriaManager.APP) .setCmd(NormalCmdFactory.getInstance() .createCmd(targetName, new UploadTaskEntity(), NormalCmdFactory.TASK_STOP_ALL, @@ -116,7 +123,7 @@ public class UploadReceiver extends AbsReceiver { * @param removeFile {@code true} 删除已经上传完成的任务,不仅删除上传记录,还会删除已经上传完成的文件,{@code false} * 如果文件已经上传完成,只删除上传记录 */ - @Override public void removeAllTask(boolean removeFile) { + public void removeAllTask(boolean removeFile) { final AriaManager am = AriaManager.getInstance(AriaManager.APP); am.setCmd(CommonUtil.createNormalCmd(targetName, new UploadTaskEntity(), @@ -129,16 +136,24 @@ public class UploadReceiver extends AbsReceiver { } @Override public void destroy() { - targetName = null; + removeObj(); } /** * 将当前类注册到Aria */ public void register() { - String className = obj.getClass().getName(); + if (TextUtils.isEmpty(targetName)) { + ALog.e(TAG, "upload register target null"); + return; + } + Object obj = OBJ_MAP.get(getKey()); + if (obj == null) { + ALog.e(TAG, String.format("【%s】观察者为空", targetName)); + return; + } Set cCounter = ProxyHelper.getInstance().uploadCounter; - if (cCounter != null && cCounter.contains(className)) { + if (cCounter != null && cCounter.contains(targetName)) { UploadSchedulers.getInstance().register(obj); } } @@ -151,13 +166,25 @@ public class UploadReceiver extends AbsReceiver { if (needRmListener) { unRegisterListener(); } - AriaManager.getInstance(AriaManager.APP).removeReceiver(obj); + AriaManager.getInstance(AriaManager.APP).removeReceiver(targetName); + } + + @Override protected String getType() { + return ReceiverType.UPLOAD; } @Override public void unRegisterListener() { - String className = obj.getClass().getName(); + if (TextUtils.isEmpty(targetName)) { + ALog.e(TAG, "upload unRegisterListener target null"); + return; + } + Object obj = OBJ_MAP.get(getKey()); + if (obj == null) { + ALog.e(TAG, String.format("【%s】观察者为空", targetName)); + return; + } Set dCounter = ProxyHelper.getInstance().uploadCounter; - if (dCounter != null && dCounter.contains(className)) { + if (dCounter != null && dCounter.contains(targetName)) { UploadSchedulers.getInstance().unRegister(obj); } } diff --git a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java index 8337a134..692a5a02 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java @@ -23,7 +23,6 @@ import android.net.Uri; import android.os.Environment; import android.text.TextUtils; import android.util.Base64; -import android.util.Log; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.FtpUrlEntity; import com.arialyy.aria.core.command.ICmd; @@ -106,6 +105,11 @@ public class CommonUtil { public static List getPkgClassName(String path, String filterClass) { List list = new ArrayList<>(); try { + File file = new File(path); + if (!file.exists()) { + ALog.w(TAG, String.format("路径【%s】下的Dex文件不存在", path)); + return list; + } DexFile df = new DexFile(path);//通过DexFile查找当前的APK中可执行文件 Enumeration enumeration = df.entries();//获取df中的元素 这里包含了所有可执行的类名 该类名包含了包名+类名的方式 diff --git a/Aria/src/main/java/com/arialyy/aria/util/FileUtil.java b/Aria/src/main/java/com/arialyy/aria/util/FileUtil.java new file mode 100644 index 00000000..b897633f --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/util/FileUtil.java @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.arialyy.aria.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.SequenceInputStream; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; +import java.nio.channels.ReadableByteChannel; +import java.util.Collections; +import java.util.Enumeration; +import java.util.LinkedList; +import java.util.List; + +/** + * 文件操作工具类 + */ +public class FileUtil { + private static final String TAG = "FileUtil"; + + /** + * 合并文件 + * + * @param targetPath 目标文件 + * @param subPaths 碎片文件路径 + */ + public static void mergeFile(String targetPath, List subPaths) { + File file = new File(targetPath); + FileOutputStream fos = null; + FileChannel foc = null; + try { + if (!file.exists()) { + file.createNewFile(); + fos = new FileOutputStream(targetPath); + foc = fos.getChannel(); + List streams = new LinkedList<>(); + for (String subPath : subPaths) { + File f = new File(subPath); + if (!f.exists()) { + ALog.d(TAG, String.format("合并文件失败,文件【%s】不存在", subPath)); + for (FileInputStream fis : streams) { + fis.close(); + } + streams.clear(); + + return; + } + streams.add(new FileInputStream(subPath)); + } + Enumeration en = Collections.enumeration(streams); + SequenceInputStream sis = new SequenceInputStream(en); + ReadableByteChannel fic = Channels.newChannel(sis); + ByteBuffer bf = ByteBuffer.allocate(8196); + while (fic.read(bf) != -1) { + bf.flip(); + foc.write(bf); + bf.compact(); + } + fic.close(); + sis.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (foc != null) { + foc.close(); + } + if (fos != null) { + fos.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * 分割文件 + * + * @param filePath 被分割的文件路径 + * @param num 分割的块数 + */ + public static void splitFile(String filePath, int num) { + try { + final File file = new File(filePath); + long size = file.length(); + FileInputStream fis = new FileInputStream(file); + FileChannel fic = fis.getChannel(); + long j = 0; + long block = size / num; + for (int i = 0; i < num; i++) { + if (i == num - 1) { + block = size - block * (num - 1); + } + String subPath = file.getPath() + "." + i + ".part"; + ALog.d(TAG, String.format("block = %s", block)); + File subFile = new File(subPath); + if (!subFile.exists()) { + subFile.createNewFile(); + } + FileOutputStream fos = new FileOutputStream(subFile); + FileChannel sfoc = fos.getChannel(); + ByteBuffer bf = ByteBuffer.allocate(8196); + int len; + //fis.skip(block * i); + while ((len = fic.read(bf)) != -1) { + bf.flip(); + sfoc.write(bf); + bf.compact(); + j += len; + if (j >= block * (i + 1)) { + break; + } + } + ALog.d(TAG, String.format("len = %s", subFile.length())); + fos.close(); + sfoc.close(); + } + fis.close(); + fic.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java index 9e93f01a..7d6bd92e 100644 --- a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java @@ -254,6 +254,6 @@ public class SingleTaskActivity extends BaseActivity { @Override protected void onStop() { super.onStop(); - //Aria.download(this).unRegister(); + Aria.download(this).unRegister(); } } \ No newline at end of file diff --git a/build.gradle b/build.gradle index 24224353..1379c998 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ task clean(type: Delete) { ext { userOrg = 'arialyy' groupId = 'com.arialyy.aria' - publishVersion = '3.4.2_dev6' + publishVersion = '3.4.3_dev1' // publishVersion = '1.0.3' //FTP插件 repoName='maven' desc = 'android 下载框架'