pull/330/head
laoyuyu 7 years ago
parent 9cad84127d
commit 82f91eb56c
  1. 76
      Aria/src/main/java/com/arialyy/aria/core/Aria.java
  2. 156
      Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
  3. 8
      Aria/src/main/java/com/arialyy/aria/core/WidgetLiftManager.java
  4. 22
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
  5. 30
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsReceiver.java
  6. 7
      Aria/src/main/java/com/arialyy/aria/core/inf/IReceiver.java
  7. 10
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java
  8. 2
      DEV_LOG.md
  9. 3
      app/src/main/java/com/arialyy/simple/base/BaseApplication.java
  10. 6
      app/src/main/java/com/arialyy/simple/download/DownloadActivity.java
  11. 12
      app/src/main/java/com/arialyy/simple/download/DownloadDialog.java
  12. 2
      app/src/main/java/com/arialyy/simple/download/DownloadDialogFragment.java
  13. 18
      app/src/main/java/com/arialyy/simple/download/DownloadPopupWindow.java
  14. 194
      app/src/main/java/com/arialyy/simple/download/SimpleNotification.java
  15. 9
      app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java
  16. 16
      app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java
  17. 2
      app/src/main/java/com/arialyy/simple/download/service_download/DownloadService.java

@ -17,14 +17,24 @@
package com.arialyy.aria.core; package com.arialyy.aria.core;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Application;
import android.app.Dialog;
import android.app.Service;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.widget.PopupWindow;
import com.arialyy.aria.core.download.DownloadReceiver; import com.arialyy.aria.core.download.DownloadReceiver;
import com.arialyy.aria.core.upload.UploadReceiver; import com.arialyy.aria.core.upload.UploadReceiver;
import com.arialyy.aria.util.ALog;
/** /**
* Created by lyy on 2016/12/1. * Created by lyy on 2016/12/1.
* https://github.com/AriaLyy/Aria *
* @see <a href="https://github.com/AriaLyy/Aria">Aria</a>
* @see <a href="https://aria.laoyuyu.me/aria_doc/">Aria doc</a>
* Aria启动管理全局任务 * Aria启动管理全局任务
* <pre> * <pre>
* <code> * <code>
@ -51,7 +61,7 @@ import com.arialyy.aria.core.upload.UploadReceiver;
* *
* <pre> * <pre>
* <code> * <code>
* Aria.init(getContext()); * Aria.init(this);
* *
* Aria.download(this) * Aria.download(this)
* .load(URL) //下载地址,必填 * .load(URL) //下载地址,必填
@ -69,45 +79,35 @@ import com.arialyy.aria.core.upload.UploadReceiver;
} }
/** /**
* 初始化下载 * 下载在当前类中调用Aria方法参数需要使用this否则将
* * 如果不是ActivityServiceApplicationDialogFragmentFragmentPopupWindowDialog对象那么你
* @param context 支持类型有ActivityServiceApplicationDialogFragmentFragmentPopupWindowDialog * 需要在对象中初始化下载前在Application或Activity初始化的时候调用{@link #init(Context)}对Aria进行初始化
*/
public static DownloadReceiver download(Context context) {
return get(context).download(context);
}
/**
* 初始化上传
* *
* @param context 支持类型有ActivityServiceApplicationDialogFragmentFragmentPopupWindowDialog * @param obj 观察者对象为本类对象使用{@code this}
*/
public static UploadReceiver upload(Context context) {
return get(context).upload(context);
}
/**
* 在任意对象中初始化下载前提是你需要在Application或Activity初始化的时候调用{@link #init(Context)}对Aria进行初始化
*
* @param obj 任意对象
*/ */
public static DownloadReceiver download(Object obj) { public static DownloadReceiver download(Object obj) {
return AriaManager.getInstance().download(obj); return get(convertContext(obj)).download(obj);
} }
/** /**
* 在任意对象中初始化上传前提是你需要在Application或Activity初始化的时候调用{@link #init(Context)}对Aria进行初始化 * 上传
* 如果不是ActivityServiceApplicationDialogFragmentFragmentPopupWindowDialog对象那么你
* 需要在对象中初始化下载前在Application或Activity初始化的时候调用{@link #init(Context)}对Aria进行初始化
* *
* @param obj 任意对象 * @param obj 观察者对象为本类对象使用{@code this}
*/ */
public static UploadReceiver upload(Object obj) { public static UploadReceiver upload(Object obj) {
return AriaManager.getInstance().upload(obj); return get(convertContext(obj)).upload(obj);
} }
/** /**
* 处理通用事件 * 处理通用事件
*/ */
public static AriaManager get(Context context) { public static AriaManager get(Context context) {
if (context == null) {
throw new NullPointerException("context 无效,请使用 download(this) 或 upload(this);"
+ "不要使用 download(getContext()) 或 upload(getContext())");
}
return AriaManager.getInstance(context); return AriaManager.getInstance(context);
} }
@ -120,4 +120,28 @@ import com.arialyy.aria.core.upload.UploadReceiver;
public static AriaManager init(Context context) { public static AriaManager init(Context context) {
return AriaManager.getInstance(context); return AriaManager.getInstance(context);
} }
private static Context convertContext(Object obj) {
if (obj instanceof Application) {
return (Application) obj;
} else if (obj instanceof Service) {
return (Service) obj;
} else if (obj instanceof Activity) {
return (Activity) obj;
} else if (obj instanceof DialogFragment) {
return ((DialogFragment) obj).getContext();
} else if (obj instanceof android.app.DialogFragment) {
return ((android.app.DialogFragment) obj).getActivity();
} else if (obj instanceof android.support.v4.app.Fragment) {
return ((Fragment) obj).getContext();
} else if (obj instanceof android.app.Fragment) {
return ((android.app.Fragment) obj).getActivity();
} else if (obj instanceof Dialog) {
return ((Dialog) obj).getContext();
} else if (obj instanceof PopupWindow) {
return ((PopupWindow) obj).getContentView().getContext();
}
ALog.e("Aria", "请使用download(this)或upload(this)");
return null;
}
} }

@ -25,20 +25,18 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import android.widget.Toast;
import com.arialyy.aria.core.command.ICmd; import com.arialyy.aria.core.command.ICmd;
import com.arialyy.aria.core.common.QueueMod; import com.arialyy.aria.core.common.QueueMod;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
import com.arialyy.aria.core.download.DownloadReceiver; import com.arialyy.aria.core.download.DownloadReceiver;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsReceiver; import com.arialyy.aria.core.inf.AbsReceiver;
import com.arialyy.aria.core.inf.IReceiver; import com.arialyy.aria.core.inf.IReceiver;
import com.arialyy.aria.core.inf.ReceiverType;
import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadReceiver; import com.arialyy.aria.core.upload.UploadReceiver;
import com.arialyy.aria.core.upload.UploadTaskEntity;
import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.orm.DelegateWrapper; import com.arialyy.aria.orm.DelegateWrapper;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
@ -63,14 +61,17 @@ import org.xml.sax.SAXException;
*/ */
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public class AriaManager { @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public class AriaManager {
private static final String TAG = "AriaManager"; private static final String TAG = "AriaManager";
private static final String DOWNLOAD = "_download";
private static final String UPLOAD = "_upload";
public static final Object LOCK = new Object(); public static final Object LOCK = new Object();
public static final String DOWNLOAD_TEMP_DIR = "/Aria/temp/download/"; public static final String DOWNLOAD_TEMP_DIR = "/Aria/temp/download/";
public static final String UPLOAD_TEMP_DIR = "/Aria/temp/upload/"; public static final String UPLOAD_TEMP_DIR = "/Aria/temp/upload/";
@SuppressLint("StaticFieldLeak") private static volatile AriaManager INSTANCE = null; @SuppressLint("StaticFieldLeak") private static volatile AriaManager INSTANCE = null;
private Map<String, AbsReceiver> mReceivers = new ConcurrentHashMap<>(); private Map<String, AbsReceiver> mReceivers = new ConcurrentHashMap<>();
/**
* activity 和其DialogFragment的映射表
*/
private Map<String, List<String>> mSubClass = new ConcurrentHashMap<>();
private List<String> mActivityCount = new ArrayList<>();
public static Context APP; public static Context APP;
private List<ICmd> mCommands = new ArrayList<>(); private List<ICmd> mCommands = new ArrayList<>();
private Configuration.DownloadConfig mDConfig; private Configuration.DownloadConfig mDConfig;
@ -225,9 +226,9 @@ import org.xml.sax.SAXException;
* 处理下载操作 * 处理下载操作
*/ */
DownloadReceiver download(Object obj) { DownloadReceiver download(Object obj) {
IReceiver receiver = mReceivers.get(getKey(true, obj)); IReceiver receiver = mReceivers.get(getKey(ReceiverType.DOWNLOAD, obj));
if (receiver == null) { if (receiver == null) {
receiver = putReceiver(true, obj); receiver = putReceiver(ReceiverType.DOWNLOAD, obj);
} }
return (receiver instanceof DownloadReceiver) ? (DownloadReceiver) receiver : null; return (receiver instanceof DownloadReceiver) ? (DownloadReceiver) receiver : null;
} }
@ -236,9 +237,9 @@ import org.xml.sax.SAXException;
* 处理上传操作 * 处理上传操作
*/ */
UploadReceiver upload(Object obj) { UploadReceiver upload(Object obj) {
IReceiver receiver = mReceivers.get(getKey(false, obj)); IReceiver receiver = mReceivers.get(getKey(ReceiverType.UPLOAD, obj));
if (receiver == null) { if (receiver == null) {
receiver = putReceiver(false, obj); receiver = putReceiver(ReceiverType.UPLOAD, obj);
} }
return (receiver instanceof UploadReceiver) ? (UploadReceiver) receiver : null; return (receiver instanceof UploadReceiver) ? (UploadReceiver) receiver : null;
} }
@ -252,22 +253,19 @@ import org.xml.sax.SAXException;
public void delRecord(int type, String key) { public void delRecord(int type, String key) {
switch (type) { switch (type) {
case 1: case 1:
DbEntity.deleteData(DownloadEntity.class, "url=?", key); DbEntity.deleteData(DownloadEntity.class, "url=? and isGroupChild='false'", key);
DbEntity.deleteData(DownloadTaskEntity.class, "key=? and isGroupTask='false'", key);
break; break;
case 2: case 2:
DbEntity.deleteData(DownloadGroupEntity.class, "groupName=?", key); DbEntity.deleteData(DownloadGroupEntity.class, "groupName=?", key);
DbEntity.deleteData(DownloadGroupTaskEntity.class, "key=?", key);
break; break;
case 3: case 3:
DbEntity.deleteData(UploadEntity.class, "filePath=?", key); DbEntity.deleteData(UploadEntity.class, "filePath=?", key);
DbEntity.deleteData(UploadTaskEntity.class, "key=?", key);
break; break;
} }
} }
private IReceiver putReceiver(boolean isDownload, Object obj) { private IReceiver putReceiver(@ReceiverType String type, Object obj) {
final String key = getKey(isDownload, obj); final String key = getKey(type, obj);
IReceiver receiver = mReceivers.get(key); IReceiver receiver = mReceivers.get(key);
boolean needRmReceiver = false; boolean needRmReceiver = false;
// 监控Dialog、fragment、popupWindow的生命周期 // 监控Dialog、fragment、popupWindow的生命周期
@ -284,58 +282,81 @@ import org.xml.sax.SAXException;
if (receiver == null) { if (receiver == null) {
AbsReceiver absReceiver; AbsReceiver absReceiver;
if (isDownload) { switch (type) {
case ReceiverType.DOWNLOAD:
absReceiver = new DownloadReceiver(); absReceiver = new DownloadReceiver();
} else { break;
case ReceiverType.UPLOAD:
absReceiver = new UploadReceiver(); absReceiver = new UploadReceiver();
break;
default:
absReceiver = new DownloadReceiver();
break;
} }
receiver = checkTarget(key, absReceiver, obj, needRmReceiver); absReceiver.targetName = obj.getClass().getName();
} AbsReceiver.OBJ_MAP.put(absReceiver.getKey(), obj);
return receiver; absReceiver.needRmListener = needRmReceiver;
mReceivers.put(key, absReceiver);
receiver = absReceiver;
} }
private AbsReceiver checkTarget(String key, AbsReceiver receiver, Object obj,
boolean needRmReceiver) {
receiver.targetName = obj.getClass().getName();
AbsReceiver.OBJ_MAP.put(receiver.getKey(), obj);
receiver.needRmListener = needRmReceiver;
mReceivers.put(key, receiver);
return receiver; return receiver;
} }
/** /**
* 根据功能类型和控件类型获取对应的key * 根据功能类型和控件类型获取对应的key
*
* @param type {@link ReceiverType}
* @param obj 观察者对象
* @return {@link #createKey(String, Object)}
*/ */
private String getKey(boolean isDownload, Object obj) { private String getKey(@ReceiverType String type, Object obj) {
String clsName = obj.getClass().getName();
String key;
if (obj instanceof DialogFragment) { if (obj instanceof DialogFragment) {
key = clsName + "_" + ((DialogFragment) obj).getActivity().getClass().getName(); relateSubClass(type, obj, ((DialogFragment) obj).getActivity());
} else if (obj instanceof android.app.DialogFragment) { } else if (obj instanceof android.app.DialogFragment) {
key = clsName + "_" + ((android.app.DialogFragment) obj).getActivity().getClass().getName(); relateSubClass(type, obj, ((android.app.DialogFragment) obj).getActivity());
} else if (obj instanceof android.support.v4.app.Fragment) { } else if (obj instanceof android.support.v4.app.Fragment) {
key = clsName + "_" + ((Fragment) obj).getActivity().getClass().getName(); relateSubClass(type, obj, ((Fragment) obj).getActivity());
} else if (obj instanceof android.app.Fragment) { } else if (obj instanceof android.app.Fragment) {
key = clsName + "_" + ((android.app.Fragment) obj).getActivity().getClass().getName(); relateSubClass(type, obj, ((android.app.Fragment) obj).getActivity());
} else if (obj instanceof Dialog) { } else if (obj instanceof Dialog) {
Activity activity = ((Dialog) obj).getOwnerActivity(); Activity activity = ((Dialog) obj).getOwnerActivity();
if (activity != null) { if (activity != null) {
key = clsName + "_" + activity.getClass().getName(); relateSubClass(type, obj, activity);
} else {
key = clsName;
} }
} else if (obj instanceof PopupWindow) { } else if (obj instanceof PopupWindow) {
Context context = ((PopupWindow) obj).getContentView().getContext(); Context context = ((PopupWindow) obj).getContentView().getContext();
if (context instanceof Activity) { if (context instanceof Activity) {
key = clsName + "_" + context.getClass().getName(); relateSubClass(type, obj, (Activity) context);
} else {
key = clsName;
} }
} else {
key = clsName;
} }
key += (isDownload ? DOWNLOAD : UPLOAD) + obj.hashCode(); return createKey(type, obj);
return key; }
/**
* 关联Activity类和Fragment间的关系
*
* @param sub Frgament或dialog类
* @param activity activity寄主类
*/
private void relateSubClass(@ReceiverType String type, Object sub, Activity activity) {
String key = createKey(type, activity);
List<String> list = mSubClass.get(key);
if (list == null) {
list = new ArrayList<>();
mSubClass.put(key, list);
}
list.add(createKey(type, sub));
}
/**
* 根据功能类型和控件类型获取对应的key
*
* @param type {@link ReceiverType}
* @param obj 观察者对象
* @return key的格式为{@code String.format("%s_%s_%s", obj.getClass().getName(), type, obj.hashCode());}
*/
private String createKey(@ReceiverType String type, Object obj) {
return String.format("%s_%s_%s", obj.getClass().getName(), type, obj.hashCode());
} }
/** /**
@ -402,25 +423,46 @@ import org.xml.sax.SAXException;
/** /**
* 移除指定对象的receiver * 移除指定对象的receiver
*/ */
public void removeReceiver(String targetName) { public void removeReceiver(Object obj) {
if (TextUtils.isEmpty(targetName)) { if (obj == null) {
ALog.e(TAG, "target name null"); ALog.e(TAG, "target obj is null");
return; return;
} }
List<String> temp = new ArrayList<>();
// 移除寄主的receiver
for (Iterator<Map.Entry<String, AbsReceiver>> iter = mReceivers.entrySet().iterator(); for (Iterator<Map.Entry<String, AbsReceiver>> iter = mReceivers.entrySet().iterator();
iter.hasNext(); ) { iter.hasNext(); ) {
Map.Entry<String, AbsReceiver> entry = iter.next(); Map.Entry<String, AbsReceiver> entry = iter.next();
String key = entry.getKey(); String key = entry.getKey();
if (key.contains(targetName)) { if (key.equals(getKey(ReceiverType.DOWNLOAD, obj)) || key.equals(
getKey(ReceiverType.UPLOAD, obj))) {
AbsReceiver receiver = mReceivers.get(key); AbsReceiver receiver = mReceivers.get(key);
List<String> subNames = mSubClass.get(key);
if (subNames != null && !subNames.isEmpty()) {
temp.addAll(subNames);
}
if (receiver != null) {
receiver.destroy();
}
iter.remove();
}
}
// 移除寄生的receiver
if (!temp.isEmpty()) {
for (Iterator<Map.Entry<String, AbsReceiver>> iter = mReceivers.entrySet().iterator();
iter.hasNext(); ) {
Map.Entry<String, AbsReceiver> entry = iter.next();
if (temp.contains(entry.getKey())) {
AbsReceiver receiver = mReceivers.get(entry.getKey());
if (receiver != null) { if (receiver != null) {
receiver.unRegisterListener();
receiver.destroy(); receiver.destroy();
} }
iter.remove(); iter.remove();
} }
} }
} }
}
/** /**
* Activity生命周期 * Activity生命周期
@ -428,7 +470,9 @@ import org.xml.sax.SAXException;
private class LifeCallback implements Application.ActivityLifecycleCallbacks { private class LifeCallback implements Application.ActivityLifecycleCallbacks {
@Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
mActivityCount.add(
String.format("%s_%s", activity.getClass().getName(), activity.hashCode()));
ALog.w(TAG, "size = " + mActivityCount.size());
} }
@Override public void onActivityStarted(Activity activity) { @Override public void onActivityStarted(Activity activity) {
@ -452,8 +496,14 @@ import org.xml.sax.SAXException;
} }
@Override public void onActivityDestroyed(Activity activity) { @Override public void onActivityDestroyed(Activity activity) {
removeReceiver(activity.getClass().getName()); removeReceiver(activity);
// TODO: 2018/4/11 维护一个activity堆栈,应用被kill,activity会回调onDestroy方法,需要考虑server后台情况 mActivityCount.remove(
String.format("%s_%s", activity.getClass().getName(), activity.hashCode()));
ALog.w(TAG, "size = " + mActivityCount.size());
if (mActivityCount.size() == 0) {
ALog.e(TAG, "gggg");
//Toast.makeText(activity, "destroy", Toast.LENGTH_SHORT).show();
}
} }
} }
} }

@ -80,7 +80,7 @@ final class WidgetLiftManager {
private PopupWindow.OnDismissListener createPopupWindowListener(final PopupWindow popupWindow) { private PopupWindow.OnDismissListener createPopupWindowListener(final PopupWindow popupWindow) {
return new PopupWindow.OnDismissListener() { return new PopupWindow.OnDismissListener() {
@Override public void onDismiss() { @Override public void onDismiss() {
AriaManager.getInstance(AriaManager.APP).removeReceiver(popupWindow.getClass().getName()); AriaManager.getInstance(AriaManager.APP).removeReceiver(popupWindow);
} }
}; };
} }
@ -120,8 +120,7 @@ final class WidgetLiftManager {
return new Dialog.OnCancelListener() { return new Dialog.OnCancelListener() {
@Override public void onCancel(DialogInterface dialog) { @Override public void onCancel(DialogInterface dialog) {
AriaManager.getInstance(AriaManager.APP) AriaManager.getInstance(AriaManager.APP).removeReceiver(dialog);
.destroySchedulerListener(dialog.getClass().getName());
} }
}; };
} }
@ -133,8 +132,7 @@ final class WidgetLiftManager {
return new Dialog.OnDismissListener() { return new Dialog.OnDismissListener() {
@Override public void onDismiss(DialogInterface dialog) { @Override public void onDismiss(DialogInterface dialog) {
AriaManager.getInstance(AriaManager.APP) AriaManager.getInstance(AriaManager.APP).removeReceiver(dialog);
.destroySchedulerListener(dialog.getClass().getName());
} }
}; };
} }

@ -253,22 +253,28 @@ public class DownloadReceiver extends AbsReceiver {
} }
/** /**
* 取消注册如果是Activity或fragmentAria会界面销毁时自动调用该方法 * 取消注册如果是Activity或fragmentAria会界面销毁时自动调用该方法不需要你手动调用
* 如果在activity中一定要调用该方法那么请在onDestroy()中调用 * 注意事项
* 如果是Dialog或popupwindow需要你在撤销界面时调用该方法 * 1如果在activity中一定要调用该方法那么请在{@code onDestroy()}中调用
* 2不要在activity的{@code onStop()}中调用改方法
* 3如果是Dialog或popupwindow需要你在撤销界面时调用该方法
* 4如果你是在Module非android组件类中注册了Aria那么你也需要在Module类中调用该方法而不是在组件类中
* 调用销毁详情见
*
* @see <a href="https://aria.laoyuyu.me/aria_doc/start/any_java.html#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9">module类中销毁</a>
*/ */
@Override public void unRegister() { @Override public void unRegister() {
if (needRmListener) { if (needRmListener) {
unRegisterListener(); unRegisterListener();
} }
AriaManager.getInstance(AriaManager.APP).removeReceiver(targetName); AriaManager.getInstance(AriaManager.APP).removeReceiver(OBJ_MAP.get(getKey()));
} }
@Override protected String getType() { @Override public String getType() {
return ReceiverType.DOWNLOAD; return ReceiverType.DOWNLOAD;
} }
@Override public void unRegisterListener() { @Override protected void unRegisterListener() {
if (TextUtils.isEmpty(targetName)) { if (TextUtils.isEmpty(targetName)) {
ALog.e(TAG, "download unRegisterListener target null"); ALog.e(TAG, "download unRegisterListener target null");
return; return;
@ -290,10 +296,6 @@ public class DownloadReceiver extends AbsReceiver {
} }
} }
@Override public void destroy() {
removeObj();
}
/** /**
* 通过下载链接获取下载实体 * 通过下载链接获取下载实体
* *

@ -30,13 +30,15 @@ import java.util.concurrent.ConcurrentHashMap;
public abstract class AbsReceiver implements IReceiver { public abstract class AbsReceiver implements IReceiver {
/** /**
* 观察者对象map * 观察者对象map
* key {@link #getKey(String, IReceiver)}指定 * key {@link #getKey(IReceiver)}指定
*/ */
public static final Map<String, Object> OBJ_MAP = new ConcurrentHashMap<>(); public static final Map<String, Object> OBJ_MAP = new ConcurrentHashMap<>();
/**
* 观察者对象类的完整名称
*/
public String targetName; public String targetName;
/** /**
* 当dialogdialogFragmentpopupwindow已经被设置了关闭监听时需要手动移除receiver * 当dialogdialogFragmentpopupwindow已经被用户使用了Dismiss事件或Cancel事件需要手动移除receiver
*/ */
public boolean needRmListener = false; public boolean needRmListener = false;
@ -44,12 +46,12 @@ public abstract class AbsReceiver implements IReceiver {
* 创建观察者对象map的key生成规则 * 创建观察者对象map的key生成规则
* {@link #targetName}_{@code download}{@code upload}_{@link #hashCode()} * {@link #targetName}_{@code download}{@code upload}_{@link #hashCode()}
* *
* @param type {@link ReceiverType}
* @param receiver 当前接收器 * @param receiver 当前接收器
* @return 返回key * @return 返回key
*/ */
public static String getKey(@ReceiverType String type, IReceiver receiver) { public static String getKey(IReceiver receiver) {
return String.format("%s_%s_%s", receiver.getTargetName(), type, receiver.hashCode()); return String.format("%s_%s_%s", receiver.getTargetName(), receiver.getType(),
receiver.hashCode());
} }
@Override public String getTargetName() { @Override public String getTargetName() {
@ -60,13 +62,13 @@ public abstract class AbsReceiver implements IReceiver {
* 获取当前Receiver的key * 获取当前Receiver的key
*/ */
@Override public String getKey() { @Override public String getKey() {
return getKey(getType(), this); return getKey(this);
} }
/** /**
* 移除观察者对象 * 移除观察者对象
*/ */
protected void removeObj() { private void removeObj() {
for (Iterator<Map.Entry<String, Object>> iter = OBJ_MAP.entrySet().iterator(); for (Iterator<Map.Entry<String, Object>> iter = OBJ_MAP.entrySet().iterator();
iter.hasNext(); ) { iter.hasNext(); ) {
Map.Entry<String, Object> entry = iter.next(); Map.Entry<String, Object> entry = iter.next();
@ -77,15 +79,13 @@ public abstract class AbsReceiver implements IReceiver {
} }
} }
/** @Override public void destroy() {
* 设置类型 unRegisterListener();
* removeObj();
* @return {@link ReceiverType} }
*/
protected abstract @ReceiverType String getType();
/** /**
* 移除{@link DownloadTaskQueue}{@link DownloadGroupTaskQueue}{@link UploadTaskQueue}中注册的观察者 * 移除{@link DownloadTaskQueue}{@link DownloadGroupTaskQueue}{@link UploadTaskQueue}中注册的观察者
*/ */
public abstract void unRegisterListener(); protected abstract void unRegisterListener();
} }

@ -43,4 +43,11 @@ public interface IReceiver {
* 获取当前Receiver的key * 获取当前Receiver的key
*/ */
String getKey(); String getKey();
/**
* 设置类型
*
* @return {@link ReceiverType}
*/
@ReceiverType String getType();
} }

@ -135,10 +135,6 @@ public class UploadReceiver extends AbsReceiver {
} }
} }
@Override public void destroy() {
removeObj();
}
/** /**
* 将当前类注册到Aria * 将当前类注册到Aria
*/ */
@ -166,14 +162,14 @@ public class UploadReceiver extends AbsReceiver {
if (needRmListener) { if (needRmListener) {
unRegisterListener(); unRegisterListener();
} }
AriaManager.getInstance(AriaManager.APP).removeReceiver(targetName); AriaManager.getInstance(AriaManager.APP).removeReceiver(OBJ_MAP.get(getKey()));
} }
@Override protected String getType() { @Override public String getType() {
return ReceiverType.UPLOAD; return ReceiverType.UPLOAD;
} }
@Override public void unRegisterListener() { @Override protected void unRegisterListener() {
if (TextUtils.isEmpty(targetName)) { if (TextUtils.isEmpty(targetName)) {
ALog.e(TAG, "upload unRegisterListener target null"); ALog.e(TAG, "upload unRegisterListener target null");
return; return;

@ -1,4 +1,6 @@
## 开发日志 ## 开发日志
+ v_3.4.3
- 修复在activity 的onStop中取消注册导致的内存泄露问题
+ v_3.4.2 + v_3.4.2
- fix bug https://github.com/AriaLyy/Aria/issues/248 - fix bug https://github.com/AriaLyy/Aria/issues/248
- fix bug https://github.com/AriaLyy/Aria/issues/247 - fix bug https://github.com/AriaLyy/Aria/issues/247

@ -19,6 +19,7 @@ package com.arialyy.simple.base;
import android.app.Application; import android.app.Application;
import android.os.Build; import android.os.Build;
import android.os.StrictMode; import android.os.StrictMode;
import com.arialyy.aria.core.Aria;
import com.arialyy.frame.core.AbsFrame; import com.arialyy.frame.core.AbsFrame;
import com.arialyy.simple.BuildConfig; import com.arialyy.simple.BuildConfig;
@ -29,7 +30,7 @@ public class BaseApplication extends Application {
@Override public void onCreate() { @Override public void onCreate() {
super.onCreate(); super.onCreate();
AbsFrame.init(this); AbsFrame.init(this);
//Aria.init(this);
if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
StrictMode.setThreadPolicy( StrictMode.setThreadPolicy(
new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build()); new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());

@ -20,7 +20,6 @@ import android.Manifest;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Gravity; import android.view.Gravity;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
@ -97,6 +96,7 @@ public class DownloadActivity extends BaseActivity<ActivityDownloadMeanBinding>
break; break;
case R.id.dialog_task: case R.id.dialog_task:
DownloadDialog dialog = new DownloadDialog(this); DownloadDialog dialog = new DownloadDialog(this);
dialog.show(); dialog.show();
//DownloadDialogFragment dialog = new DownloadDialogFragment(this); //DownloadDialogFragment dialog = new DownloadDialogFragment(this);
//dialog.show(getSupportFragmentManager(), "dialog"); //dialog.show(getSupportFragmentManager(), "dialog");
@ -109,8 +109,8 @@ public class DownloadActivity extends BaseActivity<ActivityDownloadMeanBinding>
startActivity(new Intent(this, FragmentActivity.class)); startActivity(new Intent(this, FragmentActivity.class));
break; break;
case R.id.notification: case R.id.notification:
SimpleNotification notification = new SimpleNotification(this); //SimpleNotification notification = new SimpleNotification(this);
notification.start(); //notification.start();
break; break;
} }
} }

@ -57,8 +57,8 @@ public class DownloadDialog extends AbsDialog {
} }
private void init() { private void init() {
Aria.download(getContext()).register(); Aria.download(this).register();
DownloadEntity entity = Aria.download(getContext()).getDownloadEntity(DOWNLOAD_URL); DownloadEntity entity = Aria.download(this).getDownloadEntity(DOWNLOAD_URL);
if (entity != null) { if (entity != null) {
mSize.setText(CommonUtil.formatFileSize(entity.getFileSize())); mSize.setText(CommonUtil.formatFileSize(entity.getFileSize()));
int p = (int) (entity.getCurrentProgress() * 100 / entity.getFileSize()); int p = (int) (entity.getCurrentProgress() * 100 / entity.getFileSize());
@ -73,16 +73,16 @@ public class DownloadDialog extends AbsDialog {
@OnClick({ R.id.start, R.id.stop, R.id.cancel }) public void onClick(View view) { @OnClick({ R.id.start, R.id.stop, R.id.cancel }) public void onClick(View view) {
switch (view.getId()) { switch (view.getId()) {
case R.id.start: case R.id.start:
Aria.download(getContext()) Aria.download(this)
.load(DOWNLOAD_URL) .load(DOWNLOAD_URL)
.setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/飞机大战.apk") .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/飞机大战.apk")
.start(); .start();
break; break;
case R.id.stop: case R.id.stop:
Aria.download(getContext()).load(DOWNLOAD_URL).pause(); Aria.download(this).load(DOWNLOAD_URL).stop();
break; break;
case R.id.cancel: case R.id.cancel:
Aria.download(getContext()).load(DOWNLOAD_URL).cancel(); Aria.download(this).load(DOWNLOAD_URL).cancel();
break; break;
} }
} }

@ -98,7 +98,7 @@ import com.arialyy.simple.databinding.DialogFragmentDownloadBinding;
case R.id.start: case R.id.start:
Aria.download(getContext()) Aria.download(getContext())
.load(DOWNLOAD_URL) .load(DOWNLOAD_URL)
.setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/放置江湖.apk") .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/放置江湖.apk")
.start(); .start();
break; break;
case R.id.stop: case R.id.stop:

@ -26,9 +26,9 @@ import android.widget.TextView;
import butterknife.Bind; import butterknife.Bind;
import butterknife.OnClick; import butterknife.OnClick;
import com.arialyy.annotations.Download; import com.arialyy.annotations.Download;
import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.Aria; import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.core.AbsPopupWindow; import com.arialyy.frame.core.AbsPopupWindow;
@ -59,13 +59,13 @@ public class DownloadPopupWindow extends AbsPopupWindow {
} }
private void initWidget() { private void initWidget() {
if (Aria.download(getContext()).taskExists(DOWNLOAD_URL)) { if (Aria.download(this).taskExists(DOWNLOAD_URL)) {
DownloadTarget target = Aria.download(getContext()).load(DOWNLOAD_URL); DownloadTarget target = Aria.download(this).load(DOWNLOAD_URL);
int p = (int) (target.getCurrentProgress() * 100 / target.getFileSize()); int p = (int) (target.getCurrentProgress() * 100 / target.getFileSize());
mPb.setProgress(p); mPb.setProgress(p);
} }
Aria.download(getContext()).register(); Aria.download(this).register();
DownloadEntity entity = Aria.download(getContext()).getDownloadEntity(DOWNLOAD_URL); DownloadEntity entity = Aria.download(this).getDownloadEntity(DOWNLOAD_URL);
if (entity != null) { if (entity != null) {
mSize.setText(CommonUtil.formatFileSize(entity.getFileSize())); mSize.setText(CommonUtil.formatFileSize(entity.getFileSize()));
int state = entity.getState(); int state = entity.getState();
@ -78,16 +78,16 @@ public class DownloadPopupWindow extends AbsPopupWindow {
@OnClick({ R.id.start, R.id.stop, R.id.cancel }) public void onClick(View view) { @OnClick({ R.id.start, R.id.stop, R.id.cancel }) public void onClick(View view) {
switch (view.getId()) { switch (view.getId()) {
case R.id.start: case R.id.start:
Aria.download(getContext()) Aria.download(this)
.load(DOWNLOAD_URL) .load(DOWNLOAD_URL)
.setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/消消乐.apk") .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/消消乐.apk")
.start(); .start();
break; break;
case R.id.stop: case R.id.stop:
Aria.download(getContext()).load(DOWNLOAD_URL).pause(); Aria.download(this).load(DOWNLOAD_URL).stop();
break; break;
case R.id.cancel: case R.id.cancel:
Aria.download(getContext()).load(DOWNLOAD_URL).cancel(); Aria.download(this).load(DOWNLOAD_URL).cancel();
break; break;
} }
} }

@ -1,95 +1,99 @@
/* ///*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) // * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
* // *
* Licensed under the Apache License, Version 2.0 (the "License"); // * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. // * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at // * You may obtain a copy of the License at
* // *
* http://www.apache.org/licenses/LICENSE-2.0 // * http://www.apache.org/licenses/LICENSE-2.0
* // *
* Unless required by applicable law or agreed to in writing, software // * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, // * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and // * See the License for the specific language governing permissions and
* limitations under the License. // * limitations under the License.
*/ // */
//
package com.arialyy.simple.download; //package com.arialyy.simple.download;
//
import android.app.NotificationManager; //import android.app.NotificationManager;
import android.content.Context; //import android.content.Context;
import android.os.Environment; //import android.os.Environment;
import android.support.v4.app.NotificationCompat; //import android.support.v4.app.NotificationCompat;
import com.arialyy.annotations.Download; //import com.arialyy.annotations.Download;
import com.arialyy.aria.core.Aria; //import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadTask; //import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.simple.R; //import com.arialyy.simple.R;
//
/** ///**
* Created by Aria.Lao on 2017/1/18. // * Created by Aria.Lao on 2017/1/18.
*/ // */
//
public class SimpleNotification { //public class SimpleNotification {
private static final String DOWNLOAD_URL = // private static final String DOWNLOAD_URL =
"http://static.gaoshouyou.com/d/cb/38/f0cb1b2c57388fe14342eecd64bbae65.apk"; // "http://static.gaoshouyou.com/d/cb/38/f0cb1b2c57388fe14342eecd64bbae65.apk";
//
private NotificationManager mManager; // private NotificationManager mManager;
private Context mContext; // private Context mContext;
private NotificationCompat.Builder mBuilder; // private NotificationCompat.Builder mBuilder;
private static final int mNotifiyId = 0; // private static final int mNotifiyId = 0;
//
public SimpleNotification(Context context) { // public SimpleNotification(Context context) {
mContext = context; // mContext = context;
init(); // init();
} // }
//
private void init() { // private void init() {
mManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); // mManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(mContext); // mBuilder = new NotificationCompat.Builder(mContext);
mBuilder.setContentTitle("Aria Download Test") // mBuilder.setContentTitle("Aria Download Test")
.setContentText("进度条") // .setContentText("进度条")
.setProgress(100, 0, false) // .setProgress(100, 0, false)
.setSmallIcon(R.mipmap.ic_launcher); // .setSmallIcon(R.mipmap.ic_launcher);
mManager.notify(mNotifiyId, mBuilder.build()); // mManager.notify(mNotifiyId, mBuilder.build());
Aria.download(mContext).register(); // Aria.download(this).register();
} // }
//
public void start() { // public void start() {
Aria.download(mContext) // Aria.download(this)
.load(DOWNLOAD_URL) // .load(DOWNLOAD_URL)
.setDownloadPath(Environment.getExternalStorageDirectory() + "/Download/消灭星星.apk") // .setFilePath(Environment.getExternalStorageDirectory() + "/Download/消灭星星.apk")
.start(); // .start();
} // }
//
public void stop() { // public void stop() {
Aria.download(mContext).load(DOWNLOAD_URL).pause(); // Aria.download(this).load(DOWNLOAD_URL).stop();
} // }
//
@Download.onTaskStart public void onTaskStart(DownloadTask task) { // public void destory() {
} // Aria.download(this).unRegister();
// }
@Download.onTaskPre public void onTaskPre(DownloadTask task) { //
} // @Download.onTaskStart public void onTaskStart(DownloadTask task) {
// }
@Download.onTaskStop public void onTaskStop(DownloadTask task) { //
} // @Download.onTaskPre public void onTaskPre(DownloadTask task) {
// }
@Download.onTaskRunning public void onTaskRunning(DownloadTask task) { //
long len = task.getFileSize(); // @Download.onTaskStop public void onTaskStop(DownloadTask task) {
int p = (int) (task.getCurrentProgress() * 100 / len); // }
if (mBuilder != null) { //
mBuilder.setProgress(100, p, false); // @Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
mManager.notify(mNotifiyId, mBuilder.build()); // long len = task.getFileSize();
} // int p = (int) (task.getCurrentProgress() * 100 / len);
} // if (mBuilder != null) {
// mBuilder.setProgress(100, p, false);
@Download.onTaskComplete public void onTaskComplete(DownloadTask task) { // mManager.notify(mNotifiyId, mBuilder.build());
if (mBuilder != null) { // }
mBuilder.setProgress(100, 100, false); // }
mManager.notify(mNotifiyId, mBuilder.build()); //
} // @Download.onTaskComplete public void onTaskComplete(DownloadTask task) {
} // if (mBuilder != null) {
// mBuilder.setProgress(100, 100, false);
@Download.onTaskCancel public void onTaskCancel(DownloadTask task) { // mManager.notify(mNotifiyId, mBuilder.build());
} // }
} // }
//
// @Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
// }
//}

@ -16,6 +16,7 @@
package com.arialyy.simple.download; package com.arialyy.simple.download;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.util.Log; import android.util.Log;
@ -219,13 +220,13 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
startD(); startD();
break; break;
case R.id.stop: case R.id.stop:
Aria.download(this).load(DOWNLOAD_URL).stop(); //Aria.download(this).load(DOWNLOAD_URL).stop();
//startActivity(new Intent(this, SingleTaskActivity.class)); startActivity(new Intent(this, SingleTaskActivity.class));
//Aria.download(this).load(DOWNLOAD_URL).removeRecord(); //Aria.download(this).load(DOWNLOAD_URL).removeRecord();
break; break;
case R.id.cancel: case R.id.cancel:
Aria.download(this).load(DOWNLOAD_URL).cancel(); Aria.download(this).load(DOWNLOAD_URL).cancel();
Aria.download(this).load(DOWNLOAD_URL).removeRecord(); //Aria.download(this).load(DOWNLOAD_URL).removeRecord();
break; break;
} }
} }
@ -254,6 +255,6 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
@Override protected void onStop() { @Override protected void onStop() {
super.onStop(); super.onStop();
Aria.download(this).unRegister(); //Aria.download(this).unRegister();
} }
} }

@ -45,11 +45,11 @@ public class DownloadFragment extends AbsFragment<FragmentDownloadBinding> {
private static final String DOWNLOAD_URL = "https://res5.d.cn/2137e42d610b3488d9420c6421529386eee5bdbfd9be1fafe0a05d6dabaec8c156ddbd00581055bbaeac03904fb63310e80010680235d16bd4c040b50096a0c20dd1c4b0854529a1.apk"; private static final String DOWNLOAD_URL = "https://res5.d.cn/2137e42d610b3488d9420c6421529386eee5bdbfd9be1fafe0a05d6dabaec8c156ddbd00581055bbaeac03904fb63310e80010680235d16bd4c040b50096a0c20dd1c4b0854529a1.apk";
@Override protected void init(Bundle savedInstanceState) { @Override protected void init(Bundle savedInstanceState) {
if (Aria.download(getContext()).taskExists(DOWNLOAD_URL)) { if (Aria.download(this).taskExists(DOWNLOAD_URL)) {
DownloadTarget target = Aria.download(getContext()).load(DOWNLOAD_URL); DownloadTarget target = Aria.download(this).load(DOWNLOAD_URL);
getBinding().setProgress(target.getPercent()); getBinding().setProgress(target.getPercent());
} }
DownloadEntity entity = Aria.download(getContext()).getDownloadEntity(DOWNLOAD_URL); DownloadEntity entity = Aria.download(this).getDownloadEntity(DOWNLOAD_URL);
if (entity != null) { if (entity != null) {
getBinding().setFileSize(CommonUtil.formatFileSize(entity.getFileSize())); getBinding().setFileSize(CommonUtil.formatFileSize(entity.getFileSize()));
int state = entity.getState(); int state = entity.getState();
@ -57,22 +57,22 @@ public class DownloadFragment extends AbsFragment<FragmentDownloadBinding> {
} else { } else {
setBtState(true); setBtState(true);
} }
Aria.download(getContext()).register(); Aria.download(this).register();
} }
@OnClick({ R.id.start, R.id.stop, R.id.cancel }) public void onClick(View view) { @OnClick({ R.id.start, R.id.stop, R.id.cancel }) public void onClick(View view) {
switch (view.getId()) { switch (view.getId()) {
case R.id.start: case R.id.start:
Aria.download(getContext()) Aria.download(this)
.load(DOWNLOAD_URL) .load(DOWNLOAD_URL)
.setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/王者军团.apk") .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/王者军团.apk")
.start(); .start();
break; break;
case R.id.stop: case R.id.stop:
Aria.download(getContext()).load(DOWNLOAD_URL).pause(); Aria.download(this).load(DOWNLOAD_URL).pause();
break; break;
case R.id.cancel: case R.id.cancel:
Aria.download(getContext()).load(DOWNLOAD_URL).cancel(); Aria.download(this).load(DOWNLOAD_URL).cancel();
break; break;
} }
} }

@ -48,7 +48,7 @@ public class DownloadService extends Service {
Aria.download(this).register(); Aria.download(this).register();
Aria.download(this) Aria.download(this)
.load(DOWNLOAD_URL) .load(DOWNLOAD_URL)
.setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/service_task.apk") .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/service_task.apk")
.start(); .start();
} }

Loading…
Cancel
Save