From 82f91eb56c59352b62fb947f568eb1f91f5a5a54 Mon Sep 17 00:00:00 2001 From: laoyuyu <511455842@qq.com> Date: Wed, 13 Jun 2018 20:56:18 +0800 Subject: [PATCH] fix bug --- .../main/java/com/arialyy/aria/core/Aria.java | 76 ++++--- .../com/arialyy/aria/core/AriaManager.java | 160 ++++++++++----- .../arialyy/aria/core/WidgetLiftManager.java | 8 +- .../aria/core/download/DownloadReceiver.java | 22 +- .../arialyy/aria/core/inf/AbsReceiver.java | 30 +-- .../com/arialyy/aria/core/inf/IReceiver.java | 7 + .../aria/core/upload/UploadReceiver.java | 10 +- DEV_LOG.md | 2 + .../arialyy/simple/base/BaseApplication.java | 3 +- .../simple/download/DownloadActivity.java | 6 +- .../simple/download/DownloadDialog.java | 12 +- .../download/DownloadDialogFragment.java | 2 +- .../simple/download/DownloadPopupWindow.java | 18 +- .../simple/download/SimpleNotification.java | 194 +++++++++--------- .../simple/download/SingleTaskActivity.java | 9 +- .../fragment_download/DownloadFragment.java | 16 +- .../service_download/DownloadService.java | 2 +- 17 files changed, 331 insertions(+), 246 deletions(-) diff --git a/Aria/src/main/java/com/arialyy/aria/core/Aria.java b/Aria/src/main/java/com/arialyy/aria/core/Aria.java index 10a40fa2..517d11ef 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/Aria.java +++ b/Aria/src/main/java/com/arialyy/aria/core/Aria.java @@ -17,14 +17,24 @@ package com.arialyy.aria.core; 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.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.upload.UploadReceiver; +import com.arialyy.aria.util.ALog; /** * Created by lyy on 2016/12/1. - * https://github.com/AriaLyy/Aria + * + * @see Aria + * @see Aria doc * Aria启动,管理全局任务 *
  *   
@@ -51,7 +61,7 @@ import com.arialyy.aria.core.upload.UploadReceiver;
  *
  * 
  *   
- *       Aria.init(getContext());
+ *       Aria.init(this);
  *
  *      Aria.download(this)
  *       .load(URL)     //下载地址,必填
@@ -69,45 +79,35 @@ import com.arialyy.aria.core.upload.UploadReceiver;
   }
 
   /**
-   * 初始化下载
+   * 下载,在当前类中调用Aria方法,参数需要使用this,否则将
+   * 如果不是【Activity、Service、Application、DialogFragment、Fragment、PopupWindow、Dialog】对象,那么你
+   * 需要在对象中初始化下载前,在Application或Activity初始化的时候调用{@link #init(Context)}对Aria进行初始化
    *
-   * @param context 支持类型有【Activity、Service、Application、DialogFragment、Fragment、PopupWindow、Dialog】
-   */
-  public static DownloadReceiver download(Context context) {
-    return get(context).download(context);
-  }
-
-  /**
-   * 初始化上传
-   *
-   * @param context 支持类型有【Activity、Service、Application、DialogFragment、Fragment、PopupWindow、Dialog】
-   */
-  public static UploadReceiver upload(Context context) {
-    return get(context).upload(context);
-  }
-
-  /**
-   * 在任意对象中初始化下载,前提是你需要在Application或Activity初始化的时候调用{@link #init(Context)}对Aria进行初始化
-   *
-   * @param obj 任意对象
+   * @param obj 观察者对象,为本类对象,使用{@code this}
    */
   public static DownloadReceiver download(Object obj) {
-    return AriaManager.getInstance().download(obj);
+    return get(convertContext(obj)).download(obj);
   }
 
   /**
-   * 在任意对象中初始化上传,前提是你需要在Application或Activity初始化的时候调用{@link #init(Context)}对Aria进行初始化
+   * 上传
+   * 如果不是【Activity、Service、Application、DialogFragment、Fragment、PopupWindow、Dialog】对象,那么你
+   * 需要在对象中初始化下载前,在Application或Activity初始化的时候调用{@link #init(Context)}对Aria进行初始化
    *
-   * @param obj 任意对象
+   * @param obj 观察者对象,为本类对象,使用{@code this}
    */
   public static UploadReceiver upload(Object obj) {
-    return AriaManager.getInstance().upload(obj);
+    return get(convertContext(obj)).upload(obj);
   }
 
   /**
    * 处理通用事件
    */
   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);
   }
 
@@ -120,4 +120,28 @@ import com.arialyy.aria.core.upload.UploadReceiver;
   public static AriaManager init(Context 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;
+  }
 }
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 f94b69c2..b5d45a8f 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
@@ -25,20 +25,18 @@ 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 android.widget.Toast;
 import com.arialyy.aria.core.command.ICmd;
 import com.arialyy.aria.core.common.QueueMod;
 import com.arialyy.aria.core.download.DownloadEntity;
 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.DownloadTaskEntity;
 import com.arialyy.aria.core.inf.AbsReceiver;
 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.UploadReceiver;
-import com.arialyy.aria.core.upload.UploadTaskEntity;
 import com.arialyy.aria.orm.DbEntity;
 import com.arialyy.aria.orm.DelegateWrapper;
 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 {
   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 String DOWNLOAD_TEMP_DIR = "/Aria/temp/download/";
   public static final String UPLOAD_TEMP_DIR = "/Aria/temp/upload/";
 
   @SuppressLint("StaticFieldLeak") private static volatile AriaManager INSTANCE = null;
   private Map mReceivers = new ConcurrentHashMap<>();
+  /**
+   * activity 和其Dialog、Fragment的映射表
+   */
+  private Map> mSubClass = new ConcurrentHashMap<>();
+  private List mActivityCount = new ArrayList<>();
   public static Context APP;
   private List mCommands = new ArrayList<>();
   private Configuration.DownloadConfig mDConfig;
@@ -225,9 +226,9 @@ import org.xml.sax.SAXException;
    * 处理下载操作
    */
   DownloadReceiver download(Object obj) {
-    IReceiver receiver = mReceivers.get(getKey(true, obj));
+    IReceiver receiver = mReceivers.get(getKey(ReceiverType.DOWNLOAD, obj));
     if (receiver == null) {
-      receiver = putReceiver(true, obj);
+      receiver = putReceiver(ReceiverType.DOWNLOAD, obj);
     }
     return (receiver instanceof DownloadReceiver) ? (DownloadReceiver) receiver : null;
   }
@@ -236,9 +237,9 @@ import org.xml.sax.SAXException;
    * 处理上传操作
    */
   UploadReceiver upload(Object obj) {
-    IReceiver receiver = mReceivers.get(getKey(false, obj));
+    IReceiver receiver = mReceivers.get(getKey(ReceiverType.UPLOAD, obj));
     if (receiver == null) {
-      receiver = putReceiver(false, obj);
+      receiver = putReceiver(ReceiverType.UPLOAD, obj);
     }
     return (receiver instanceof UploadReceiver) ? (UploadReceiver) receiver : null;
   }
@@ -252,22 +253,19 @@ import org.xml.sax.SAXException;
   public void delRecord(int type, String key) {
     switch (type) {
       case 1:
-        DbEntity.deleteData(DownloadEntity.class, "url=?", key);
-        DbEntity.deleteData(DownloadTaskEntity.class, "key=? and isGroupTask='false'", key);
+        DbEntity.deleteData(DownloadEntity.class, "url=? and isGroupChild='false'", key);
         break;
       case 2:
         DbEntity.deleteData(DownloadGroupEntity.class, "groupName=?", key);
-        DbEntity.deleteData(DownloadGroupTaskEntity.class, "key=?", key);
         break;
       case 3:
         DbEntity.deleteData(UploadEntity.class, "filePath=?", key);
-        DbEntity.deleteData(UploadTaskEntity.class, "key=?", key);
         break;
     }
   }
 
-  private IReceiver putReceiver(boolean isDownload, Object obj) {
-    final String key = getKey(isDownload, obj);
+  private IReceiver putReceiver(@ReceiverType String type, Object obj) {
+    final String key = getKey(type, obj);
     IReceiver receiver = mReceivers.get(key);
     boolean needRmReceiver = false;
     // 监控Dialog、fragment、popupWindow的生命周期
@@ -284,58 +282,81 @@ import org.xml.sax.SAXException;
 
     if (receiver == null) {
       AbsReceiver absReceiver;
-      if (isDownload) {
-        absReceiver = new DownloadReceiver();
-      } else {
-        absReceiver = new UploadReceiver();
+      switch (type) {
+        case ReceiverType.DOWNLOAD:
+          absReceiver = new DownloadReceiver();
+          break;
+        case ReceiverType.UPLOAD:
+          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);
+      absReceiver.needRmListener = needRmReceiver;
+      mReceivers.put(key, absReceiver);
+      receiver = absReceiver;
     }
     return receiver;
   }
 
-  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;
-  }
-
   /**
    * 根据功能类型和控件类型获取对应的key
+   *
+   * @param type {@link ReceiverType}
+   * @param obj 观察者对象
+   * @return {@link #createKey(String, Object)}
    */
-  private String getKey(boolean isDownload, Object obj) {
-    String clsName = obj.getClass().getName();
-    String key;
+  private String getKey(@ReceiverType String type, Object obj) {
     if (obj instanceof DialogFragment) {
-      key = clsName + "_" + ((DialogFragment) obj).getActivity().getClass().getName();
+      relateSubClass(type, obj, ((DialogFragment) obj).getActivity());
     } 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) {
-      key = clsName + "_" + ((Fragment) obj).getActivity().getClass().getName();
+      relateSubClass(type, obj, ((Fragment) obj).getActivity());
     } 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) {
       Activity activity = ((Dialog) obj).getOwnerActivity();
       if (activity != null) {
-        key = clsName + "_" + activity.getClass().getName();
-      } else {
-        key = clsName;
+        relateSubClass(type, obj, activity);
       }
     } else if (obj instanceof PopupWindow) {
       Context context = ((PopupWindow) obj).getContentView().getContext();
       if (context instanceof Activity) {
-        key = clsName + "_" + context.getClass().getName();
-      } else {
-        key = clsName;
+        relateSubClass(type, obj, (Activity) context);
       }
-    } else {
-      key = clsName;
     }
-    key += (isDownload ? DOWNLOAD : UPLOAD) + obj.hashCode();
-    return key;
+    return createKey(type, obj);
+  }
+
+  /**
+   * 关联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 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,24 +423,45 @@ import org.xml.sax.SAXException;
   /**
    * 移除指定对象的receiver
    */
-  public void removeReceiver(String targetName) {
-    if (TextUtils.isEmpty(targetName)) {
-      ALog.e(TAG, "target name null");
+  public void removeReceiver(Object obj) {
+    if (obj == null) {
+      ALog.e(TAG, "target obj is null");
       return;
     }
+    List temp = new ArrayList<>();
+    // 移除寄主的receiver
     for (Iterator> iter = mReceivers.entrySet().iterator();
         iter.hasNext(); ) {
       Map.Entry entry = iter.next();
       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);
+        List subNames = mSubClass.get(key);
+        if (subNames != null && !subNames.isEmpty()) {
+          temp.addAll(subNames);
+        }
         if (receiver != null) {
-          receiver.unRegisterListener();
           receiver.destroy();
         }
         iter.remove();
       }
     }
+
+    // 移除寄生的receiver
+    if (!temp.isEmpty()) {
+      for (Iterator> iter = mReceivers.entrySet().iterator();
+          iter.hasNext(); ) {
+        Map.Entry entry = iter.next();
+        if (temp.contains(entry.getKey())) {
+          AbsReceiver receiver = mReceivers.get(entry.getKey());
+          if (receiver != null) {
+            receiver.destroy();
+          }
+          iter.remove();
+        }
+      }
+    }
   }
 
   /**
@@ -428,7 +470,9 @@ import org.xml.sax.SAXException;
   private class LifeCallback implements Application.ActivityLifecycleCallbacks {
 
     @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) {
@@ -452,8 +496,14 @@ import org.xml.sax.SAXException;
     }
 
     @Override public void onActivityDestroyed(Activity activity) {
-      removeReceiver(activity.getClass().getName());
-      // TODO: 2018/4/11 维护一个activity堆栈,应用被kill,activity会回调onDestroy方法,需要考虑server后台情况
+      removeReceiver(activity);
+      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();
+      }
     }
   }
 }
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 32f970b8..d115084c 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).removeReceiver(popupWindow.getClass().getName());
+        AriaManager.getInstance(AriaManager.APP).removeReceiver(popupWindow);
       }
     };
   }
@@ -120,8 +120,7 @@ final class WidgetLiftManager {
     return new Dialog.OnCancelListener() {
 
       @Override public void onCancel(DialogInterface dialog) {
-        AriaManager.getInstance(AriaManager.APP)
-            .destroySchedulerListener(dialog.getClass().getName());
+        AriaManager.getInstance(AriaManager.APP).removeReceiver(dialog);
       }
     };
   }
@@ -133,8 +132,7 @@ final class WidgetLiftManager {
     return new Dialog.OnDismissListener() {
 
       @Override public void onDismiss(DialogInterface dialog) {
-        AriaManager.getInstance(AriaManager.APP)
-            .destroySchedulerListener(dialog.getClass().getName());
+        AriaManager.getInstance(AriaManager.APP).removeReceiver(dialog);
       }
     };
   }
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 909e564c..3cb4301f 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
@@ -253,22 +253,28 @@ public class DownloadReceiver extends AbsReceiver {
   }
 
   /**
-   * 取消注册,如果是Activity或fragment,Aria会界面销毁时自动调用该方法。
-   * 如果在activity中一定要调用该方法,那么请在onDestroy()中调用
-   * 如果是Dialog或popupwindow,需要你在撤销界面时调用该方法
+   * 取消注册,如果是Activity或fragment,Aria会界面销毁时自动调用该方法,不需要你手动调用。
+   * 注意事项:
+   * 1、如果在activity中一定要调用该方法,那么请在{@code onDestroy()}中调用
+   * 2、不要在activity的{@code onStop()}中调用改方法
+   * 3、如果是Dialog或popupwindow,需要你在撤销界面时调用该方法
+   * 4、如果你是在Module(非android组件类)中注册了Aria,那么你也需要在Module类中调用该方法,而不是在组件类中
+   * 调用销毁,详情见
+   *
+   * @see module类中销毁
    */
   @Override public void unRegister() {
     if (needRmListener) {
       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;
   }
 
-  @Override public void unRegisterListener() {
+  @Override protected void unRegisterListener() {
     if (TextUtils.isEmpty(targetName)) {
       ALog.e(TAG, "download unRegisterListener target null");
       return;
@@ -290,10 +296,6 @@ public class DownloadReceiver extends AbsReceiver {
     }
   }
 
-  @Override public void destroy() {
-    removeObj();
-  }
-
   /**
    * 通过下载链接获取下载实体
    *
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 dc1c2d04..5d8fefed 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
@@ -30,13 +30,15 @@ import java.util.concurrent.ConcurrentHashMap;
 public abstract class AbsReceiver implements IReceiver {
   /**
    * 观察者对象map
-   * key 由 {@link #getKey(String, IReceiver)}指定
+   * key 由 {@link #getKey(IReceiver)}指定
    */
   public static final Map OBJ_MAP = new ConcurrentHashMap<>();
-
+  /**
+   * 观察者对象类的完整名称
+   */
   public String targetName;
   /**
-   * 当dialog、dialogFragment、popupwindow已经被设置了关闭监听时,需要手动移除receiver
+   * 当dialog、dialogFragment、popupwindow已经被用户使用了Dismiss事件或Cancel事件,需要手动移除receiver
    */
   public boolean needRmListener = false;
 
@@ -44,12 +46,12 @@ public abstract class AbsReceiver implements IReceiver {
    * 创建观察者对象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());
+  public static String getKey(IReceiver receiver) {
+    return String.format("%s_%s_%s", receiver.getTargetName(), receiver.getType(),
+        receiver.hashCode());
   }
 
   @Override public String getTargetName() {
@@ -60,13 +62,13 @@ public abstract class AbsReceiver implements IReceiver {
    * 获取当前Receiver的key
    */
   @Override public String getKey() {
-    return getKey(getType(), this);
+    return getKey(this);
   }
 
   /**
    * 移除观察者对象
    */
-  protected void removeObj() {
+  private void removeObj() {
     for (Iterator> iter = OBJ_MAP.entrySet().iterator();
         iter.hasNext(); ) {
       Map.Entry entry = iter.next();
@@ -77,15 +79,13 @@ public abstract class AbsReceiver implements IReceiver {
     }
   }
 
-  /**
-   * 设置类型
-   *
-   * @return {@link ReceiverType}
-   */
-  protected abstract @ReceiverType String getType();
+  @Override public void destroy() {
+    unRegisterListener();
+    removeObj();
+  }
 
   /**
    * 移除{@link DownloadTaskQueue}、{@link DownloadGroupTaskQueue}、{@link UploadTaskQueue}中注册的观察者
    */
-  public abstract void unRegisterListener();
+  protected 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 639dc24d..a4fb92b1 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
@@ -43,4 +43,11 @@ public interface IReceiver {
    * 获取当前Receiver的key
    */
   String getKey();
+
+  /**
+   * 设置类型
+   *
+   * @return {@link ReceiverType}
+   */
+  @ReceiverType String getType();
 }
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 aa0d63f6..e5fd9cca 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
@@ -135,10 +135,6 @@ public class UploadReceiver extends AbsReceiver {
     }
   }
 
-  @Override public void destroy() {
-    removeObj();
-  }
-
   /**
    * 将当前类注册到Aria
    */
@@ -166,14 +162,14 @@ public class UploadReceiver extends AbsReceiver {
     if (needRmListener) {
       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;
   }
 
-  @Override public void unRegisterListener() {
+  @Override protected void unRegisterListener() {
     if (TextUtils.isEmpty(targetName)) {
       ALog.e(TAG, "upload unRegisterListener target null");
       return;
diff --git a/DEV_LOG.md b/DEV_LOG.md
index 20a60579..5098f4fa 100644
--- a/DEV_LOG.md
+++ b/DEV_LOG.md
@@ -1,4 +1,6 @@
 ## 开发日志
+  + v_3.4.3
+    - 修复在activity 的onStop中取消注册导致的内存泄露问题
   + v_3.4.2
     - fix bug https://github.com/AriaLyy/Aria/issues/248
     - fix bug https://github.com/AriaLyy/Aria/issues/247
diff --git a/app/src/main/java/com/arialyy/simple/base/BaseApplication.java b/app/src/main/java/com/arialyy/simple/base/BaseApplication.java
index 29cda1b9..c4fe6368 100644
--- a/app/src/main/java/com/arialyy/simple/base/BaseApplication.java
+++ b/app/src/main/java/com/arialyy/simple/base/BaseApplication.java
@@ -19,6 +19,7 @@ package com.arialyy.simple.base;
 import android.app.Application;
 import android.os.Build;
 import android.os.StrictMode;
+import com.arialyy.aria.core.Aria;
 import com.arialyy.frame.core.AbsFrame;
 import com.arialyy.simple.BuildConfig;
 
@@ -29,7 +30,7 @@ public class BaseApplication extends Application {
   @Override public void onCreate() {
     super.onCreate();
     AbsFrame.init(this);
-
+    //Aria.init(this);
     if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
       StrictMode.setThreadPolicy(
           new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
diff --git a/app/src/main/java/com/arialyy/simple/download/DownloadActivity.java b/app/src/main/java/com/arialyy/simple/download/DownloadActivity.java
index 84cd2cd5..3e965d4c 100644
--- a/app/src/main/java/com/arialyy/simple/download/DownloadActivity.java
+++ b/app/src/main/java/com/arialyy/simple/download/DownloadActivity.java
@@ -20,7 +20,6 @@ import android.Manifest;
 import android.content.Intent;
 import android.os.Build;
 import android.os.Bundle;
-import android.support.v7.widget.Toolbar;
 import android.view.Gravity;
 import android.view.View;
 import android.widget.Button;
@@ -97,6 +96,7 @@ public class DownloadActivity extends BaseActivity
         break;
       case R.id.dialog_task:
         DownloadDialog dialog = new DownloadDialog(this);
+
         dialog.show();
         //DownloadDialogFragment dialog = new DownloadDialogFragment(this);
         //dialog.show(getSupportFragmentManager(), "dialog");
@@ -109,8 +109,8 @@ public class DownloadActivity extends BaseActivity
         startActivity(new Intent(this, FragmentActivity.class));
         break;
       case R.id.notification:
-        SimpleNotification notification = new SimpleNotification(this);
-        notification.start();
+        //SimpleNotification notification = new SimpleNotification(this);
+        //notification.start();
         break;
     }
   }
diff --git a/app/src/main/java/com/arialyy/simple/download/DownloadDialog.java b/app/src/main/java/com/arialyy/simple/download/DownloadDialog.java
index 68d656e4..e5673c44 100644
--- a/app/src/main/java/com/arialyy/simple/download/DownloadDialog.java
+++ b/app/src/main/java/com/arialyy/simple/download/DownloadDialog.java
@@ -57,8 +57,8 @@ public class DownloadDialog extends AbsDialog {
   }
 
   private void init() {
-    Aria.download(getContext()).register();
-    DownloadEntity entity = Aria.download(getContext()).getDownloadEntity(DOWNLOAD_URL);
+    Aria.download(this).register();
+    DownloadEntity entity = Aria.download(this).getDownloadEntity(DOWNLOAD_URL);
     if (entity != null) {
       mSize.setText(CommonUtil.formatFileSize(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) {
     switch (view.getId()) {
       case R.id.start:
-        Aria.download(getContext())
+        Aria.download(this)
             .load(DOWNLOAD_URL)
-            .setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/飞机大战.apk")
+            .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/飞机大战.apk")
             .start();
         break;
       case R.id.stop:
-        Aria.download(getContext()).load(DOWNLOAD_URL).pause();
+        Aria.download(this).load(DOWNLOAD_URL).stop();
         break;
       case R.id.cancel:
-        Aria.download(getContext()).load(DOWNLOAD_URL).cancel();
+        Aria.download(this).load(DOWNLOAD_URL).cancel();
         break;
     }
   }
diff --git a/app/src/main/java/com/arialyy/simple/download/DownloadDialogFragment.java b/app/src/main/java/com/arialyy/simple/download/DownloadDialogFragment.java
index ec7a0153..91a091fb 100644
--- a/app/src/main/java/com/arialyy/simple/download/DownloadDialogFragment.java
+++ b/app/src/main/java/com/arialyy/simple/download/DownloadDialogFragment.java
@@ -98,7 +98,7 @@ import com.arialyy.simple.databinding.DialogFragmentDownloadBinding;
       case R.id.start:
         Aria.download(getContext())
             .load(DOWNLOAD_URL)
-            .setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/放置江湖.apk")
+            .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/放置江湖.apk")
             .start();
         break;
       case R.id.stop:
diff --git a/app/src/main/java/com/arialyy/simple/download/DownloadPopupWindow.java b/app/src/main/java/com/arialyy/simple/download/DownloadPopupWindow.java
index f6fae8ac..d1684ca2 100644
--- a/app/src/main/java/com/arialyy/simple/download/DownloadPopupWindow.java
+++ b/app/src/main/java/com/arialyy/simple/download/DownloadPopupWindow.java
@@ -26,9 +26,9 @@ import android.widget.TextView;
 import butterknife.Bind;
 import butterknife.OnClick;
 import com.arialyy.annotations.Download;
-import com.arialyy.aria.core.download.DownloadTarget;
 import com.arialyy.aria.core.Aria;
 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.util.CommonUtil;
 import com.arialyy.frame.core.AbsPopupWindow;
@@ -59,13 +59,13 @@ public class DownloadPopupWindow extends AbsPopupWindow {
   }
 
   private void initWidget() {
-    if (Aria.download(getContext()).taskExists(DOWNLOAD_URL)) {
-      DownloadTarget target = Aria.download(getContext()).load(DOWNLOAD_URL);
+    if (Aria.download(this).taskExists(DOWNLOAD_URL)) {
+      DownloadTarget target = Aria.download(this).load(DOWNLOAD_URL);
       int p = (int) (target.getCurrentProgress() * 100 / target.getFileSize());
       mPb.setProgress(p);
     }
-    Aria.download(getContext()).register();
-    DownloadEntity entity = Aria.download(getContext()).getDownloadEntity(DOWNLOAD_URL);
+    Aria.download(this).register();
+    DownloadEntity entity = Aria.download(this).getDownloadEntity(DOWNLOAD_URL);
     if (entity != null) {
       mSize.setText(CommonUtil.formatFileSize(entity.getFileSize()));
       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) {
     switch (view.getId()) {
       case R.id.start:
-        Aria.download(getContext())
+        Aria.download(this)
             .load(DOWNLOAD_URL)
-            .setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/消消乐.apk")
+            .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/消消乐.apk")
             .start();
         break;
       case R.id.stop:
-        Aria.download(getContext()).load(DOWNLOAD_URL).pause();
+        Aria.download(this).load(DOWNLOAD_URL).stop();
         break;
       case R.id.cancel:
-        Aria.download(getContext()).load(DOWNLOAD_URL).cancel();
+        Aria.download(this).load(DOWNLOAD_URL).cancel();
         break;
     }
   }
diff --git a/app/src/main/java/com/arialyy/simple/download/SimpleNotification.java b/app/src/main/java/com/arialyy/simple/download/SimpleNotification.java
index a2e47588..23346c15 100644
--- a/app/src/main/java/com/arialyy/simple/download/SimpleNotification.java
+++ b/app/src/main/java/com/arialyy/simple/download/SimpleNotification.java
@@ -1,95 +1,99 @@
-/*
- * 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.simple.download;
-
-import android.app.NotificationManager;
-import android.content.Context;
-import android.os.Environment;
-import android.support.v4.app.NotificationCompat;
-import com.arialyy.annotations.Download;
-import com.arialyy.aria.core.Aria;
-import com.arialyy.aria.core.download.DownloadTask;
-import com.arialyy.simple.R;
-
-/**
- * Created by Aria.Lao on 2017/1/18.
- */
-
-public class SimpleNotification {
-  private static final String DOWNLOAD_URL =
-      "http://static.gaoshouyou.com/d/cb/38/f0cb1b2c57388fe14342eecd64bbae65.apk";
-
-  private NotificationManager mManager;
-  private Context mContext;
-  private NotificationCompat.Builder mBuilder;
-  private static final int mNotifiyId = 0;
-
-  public SimpleNotification(Context context) {
-    mContext = context;
-    init();
-  }
-
-  private void init() {
-    mManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
-    mBuilder = new NotificationCompat.Builder(mContext);
-    mBuilder.setContentTitle("Aria Download Test")
-        .setContentText("进度条")
-        .setProgress(100, 0, false)
-        .setSmallIcon(R.mipmap.ic_launcher);
-    mManager.notify(mNotifiyId, mBuilder.build());
-    Aria.download(mContext).register();
-  }
-
-  public void start() {
-    Aria.download(mContext)
-        .load(DOWNLOAD_URL)
-        .setDownloadPath(Environment.getExternalStorageDirectory() + "/Download/消灭星星.apk")
-        .start();
-  }
-
-  public void stop() {
-    Aria.download(mContext).load(DOWNLOAD_URL).pause();
-  }
-
-  @Download.onTaskStart public void onTaskStart(DownloadTask task) {
-  }
-
-  @Download.onTaskPre public void onTaskPre(DownloadTask task) {
-  }
-
-  @Download.onTaskStop public void onTaskStop(DownloadTask task) {
-  }
-
-  @Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
-    long len = task.getFileSize();
-    int p = (int) (task.getCurrentProgress() * 100 / len);
-    if (mBuilder != null) {
-      mBuilder.setProgress(100, p, false);
-      mManager.notify(mNotifiyId, mBuilder.build());
-    }
-  }
-
-  @Download.onTaskComplete public void onTaskComplete(DownloadTask task) {
-    if (mBuilder != null) {
-      mBuilder.setProgress(100, 100, false);
-      mManager.notify(mNotifiyId, mBuilder.build());
-    }
-  }
-
-  @Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
-  }
-}
+///*
+// * 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.simple.download;
+//
+//import android.app.NotificationManager;
+//import android.content.Context;
+//import android.os.Environment;
+//import android.support.v4.app.NotificationCompat;
+//import com.arialyy.annotations.Download;
+//import com.arialyy.aria.core.Aria;
+//import com.arialyy.aria.core.download.DownloadTask;
+//import com.arialyy.simple.R;
+//
+///**
+// * Created by Aria.Lao on 2017/1/18.
+// */
+//
+//public class SimpleNotification {
+//  private static final String DOWNLOAD_URL =
+//      "http://static.gaoshouyou.com/d/cb/38/f0cb1b2c57388fe14342eecd64bbae65.apk";
+//
+//  private NotificationManager mManager;
+//  private Context mContext;
+//  private NotificationCompat.Builder mBuilder;
+//  private static final int mNotifiyId = 0;
+//
+//  public SimpleNotification(Context context) {
+//    mContext = context;
+//    init();
+//  }
+//
+//  private void init() {
+//    mManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+//    mBuilder = new NotificationCompat.Builder(mContext);
+//    mBuilder.setContentTitle("Aria Download Test")
+//        .setContentText("进度条")
+//        .setProgress(100, 0, false)
+//        .setSmallIcon(R.mipmap.ic_launcher);
+//    mManager.notify(mNotifiyId, mBuilder.build());
+//    Aria.download(this).register();
+//  }
+//
+//  public void start() {
+//    Aria.download(this)
+//        .load(DOWNLOAD_URL)
+//        .setFilePath(Environment.getExternalStorageDirectory() + "/Download/消灭星星.apk")
+//        .start();
+//  }
+//
+//  public void stop() {
+//    Aria.download(this).load(DOWNLOAD_URL).stop();
+//  }
+//
+//  public void destory() {
+//    Aria.download(this).unRegister();
+//  }
+//
+//  @Download.onTaskStart public void onTaskStart(DownloadTask task) {
+//  }
+//
+//  @Download.onTaskPre public void onTaskPre(DownloadTask task) {
+//  }
+//
+//  @Download.onTaskStop public void onTaskStop(DownloadTask task) {
+//  }
+//
+//  @Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
+//    long len = task.getFileSize();
+//    int p = (int) (task.getCurrentProgress() * 100 / len);
+//    if (mBuilder != null) {
+//      mBuilder.setProgress(100, p, false);
+//      mManager.notify(mNotifiyId, mBuilder.build());
+//    }
+//  }
+//
+//  @Download.onTaskComplete public void onTaskComplete(DownloadTask task) {
+//    if (mBuilder != null) {
+//      mBuilder.setProgress(100, 100, false);
+//      mManager.notify(mNotifiyId, mBuilder.build());
+//    }
+//  }
+//
+//  @Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
+//  }
+//}
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 7d6bd92e..8d5e1477 100644
--- a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java
+++ b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java
@@ -16,6 +16,7 @@
 
 package com.arialyy.simple.download;
 
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.Environment;
 import android.util.Log;
@@ -219,13 +220,13 @@ public class SingleTaskActivity extends BaseActivity {
         startD();
         break;
       case R.id.stop:
-        Aria.download(this).load(DOWNLOAD_URL).stop();
-        //startActivity(new Intent(this, SingleTaskActivity.class));
+        //Aria.download(this).load(DOWNLOAD_URL).stop();
+        startActivity(new Intent(this, SingleTaskActivity.class));
         //Aria.download(this).load(DOWNLOAD_URL).removeRecord();
         break;
       case R.id.cancel:
         Aria.download(this).load(DOWNLOAD_URL).cancel();
-        Aria.download(this).load(DOWNLOAD_URL).removeRecord();
+        //Aria.download(this).load(DOWNLOAD_URL).removeRecord();
         break;
     }
   }
@@ -254,6 +255,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/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java b/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java
index 068ac47f..d8ba2fb4 100644
--- a/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java
+++ b/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java
@@ -45,11 +45,11 @@ public class DownloadFragment extends AbsFragment {
   private static final String DOWNLOAD_URL = "https://res5.d.cn/2137e42d610b3488d9420c6421529386eee5bdbfd9be1fafe0a05d6dabaec8c156ddbd00581055bbaeac03904fb63310e80010680235d16bd4c040b50096a0c20dd1c4b0854529a1.apk";
 
   @Override protected void init(Bundle savedInstanceState) {
-    if (Aria.download(getContext()).taskExists(DOWNLOAD_URL)) {
-      DownloadTarget target = Aria.download(getContext()).load(DOWNLOAD_URL);
+    if (Aria.download(this).taskExists(DOWNLOAD_URL)) {
+      DownloadTarget target = Aria.download(this).load(DOWNLOAD_URL);
       getBinding().setProgress(target.getPercent());
     }
-    DownloadEntity entity = Aria.download(getContext()).getDownloadEntity(DOWNLOAD_URL);
+    DownloadEntity entity = Aria.download(this).getDownloadEntity(DOWNLOAD_URL);
     if (entity != null) {
       getBinding().setFileSize(CommonUtil.formatFileSize(entity.getFileSize()));
       int state = entity.getState();
@@ -57,22 +57,22 @@ public class DownloadFragment extends AbsFragment {
     } else {
       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) {
     switch (view.getId()) {
       case R.id.start:
-        Aria.download(getContext())
+        Aria.download(this)
             .load(DOWNLOAD_URL)
-            .setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/王者军团.apk")
+            .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/王者军团.apk")
             .start();
         break;
       case R.id.stop:
-        Aria.download(getContext()).load(DOWNLOAD_URL).pause();
+        Aria.download(this).load(DOWNLOAD_URL).pause();
         break;
       case R.id.cancel:
-        Aria.download(getContext()).load(DOWNLOAD_URL).cancel();
+        Aria.download(this).load(DOWNLOAD_URL).cancel();
         break;
     }
   }
diff --git a/app/src/main/java/com/arialyy/simple/download/service_download/DownloadService.java b/app/src/main/java/com/arialyy/simple/download/service_download/DownloadService.java
index bbd5357c..4994bfaa 100644
--- a/app/src/main/java/com/arialyy/simple/download/service_download/DownloadService.java
+++ b/app/src/main/java/com/arialyy/simple/download/service_download/DownloadService.java
@@ -48,7 +48,7 @@ public class DownloadService extends Service {
     Aria.download(this).register();
     Aria.download(this)
         .load(DOWNLOAD_URL)
-        .setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/service_task.apk")
+        .setFilePath(Environment.getExternalStorageDirectory().getPath() + "/service_task.apk")
         .start();
   }