修复DialogFragment 销毁时不能被Aria移除的问题
This commit is contained in:
@@ -24,6 +24,7 @@ import android.app.Service;
|
||||
import android.content.Context;
|
||||
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.util.Log;
|
||||
@@ -32,6 +33,7 @@ import com.arialyy.aria.core.common.QueueMod;
|
||||
import com.arialyy.aria.core.download.DownloadReceiver;
|
||||
import com.arialyy.aria.core.command.ICmd;
|
||||
import com.arialyy.aria.core.inf.IReceiver;
|
||||
import com.arialyy.aria.core.scheduler.AbsSchedulerListener;
|
||||
import com.arialyy.aria.core.upload.UploadReceiver;
|
||||
import com.arialyy.aria.orm.DbUtil;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
@@ -185,11 +187,16 @@ import org.xml.sax.SAXException;
|
||||
private IReceiver putReceiver(boolean isDownload, Object obj) {
|
||||
final String key = getKey(isDownload, obj);
|
||||
IReceiver receiver = mReceivers.get(key);
|
||||
boolean needRmReceiver = false;
|
||||
final WidgetLiftManager widgetLiftManager = new WidgetLiftManager();
|
||||
if (obj instanceof Dialog) {
|
||||
widgetLiftManager.handleDialogLift((Dialog) obj);
|
||||
needRmReceiver = widgetLiftManager.handleDialogLift((Dialog) obj);
|
||||
} else if (obj instanceof PopupWindow) {
|
||||
widgetLiftManager.handlePopupWindowLift((PopupWindow) obj);
|
||||
needRmReceiver = widgetLiftManager.handlePopupWindowLift((PopupWindow) obj);
|
||||
} else if (obj instanceof DialogFragment) {
|
||||
needRmReceiver = widgetLiftManager.handleDialogFragmentLift((DialogFragment) obj);
|
||||
} else if (obj instanceof android.app.DialogFragment) {
|
||||
needRmReceiver = widgetLiftManager.handleDialogFragmentLift((android.app.DialogFragment) obj);
|
||||
}
|
||||
|
||||
if (receiver == null) {
|
||||
@@ -197,12 +204,14 @@ import org.xml.sax.SAXException;
|
||||
DownloadReceiver dReceiver = new DownloadReceiver();
|
||||
dReceiver.targetName = obj.getClass().getName();
|
||||
dReceiver.obj = obj;
|
||||
dReceiver.needRmReceiver = needRmReceiver;
|
||||
mReceivers.put(key, dReceiver);
|
||||
receiver = dReceiver;
|
||||
} else {
|
||||
UploadReceiver uReceiver = new UploadReceiver();
|
||||
uReceiver.targetName = obj.getClass().getName();
|
||||
uReceiver.obj = obj;
|
||||
uReceiver.needRmReceiver = needRmReceiver;
|
||||
mReceivers.put(key, uReceiver);
|
||||
receiver = uReceiver;
|
||||
}
|
||||
@@ -217,7 +226,11 @@ import org.xml.sax.SAXException;
|
||||
String clsName = obj.getClass().getName();
|
||||
String key = "";
|
||||
if (!(obj instanceof Activity)) {
|
||||
if (obj instanceof android.support.v4.app.Fragment) {
|
||||
if (obj instanceof DialogFragment) {
|
||||
key = clsName + "_" + ((DialogFragment) obj).getActivity().getClass().getName();
|
||||
} else if (obj instanceof android.app.DialogFragment) {
|
||||
key = clsName + "_" + ((android.app.DialogFragment) obj).getActivity().getClass().getName();
|
||||
} else if (obj instanceof android.support.v4.app.Fragment) {
|
||||
key = clsName + "_" + ((Fragment) obj).getActivity().getClass().getName();
|
||||
} else if (obj instanceof android.app.Fragment) {
|
||||
key = clsName + "_" + ((android.app.Fragment) obj).getActivity().getClass().getName();
|
||||
@@ -314,7 +327,22 @@ import org.xml.sax.SAXException;
|
||||
}
|
||||
|
||||
/**
|
||||
* onDestroy
|
||||
* 移除指定对象的receiver
|
||||
*/
|
||||
public void removeReceiver(Object obj) {
|
||||
String clsName = obj.getClass().getName();
|
||||
for (Iterator<Map.Entry<String, IReceiver>> iter = mReceivers.entrySet().iterator();
|
||||
iter.hasNext(); ) {
|
||||
Map.Entry<String, IReceiver> entry = iter.next();
|
||||
String key = entry.getKey();
|
||||
if (key.contains(clsName)) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Aria注册对象被销毁时调用
|
||||
*/
|
||||
void destroySchedulerListener(Object obj) {
|
||||
String clsName = obj.getClass().getName();
|
||||
@@ -324,9 +352,11 @@ import org.xml.sax.SAXException;
|
||||
String key = entry.getKey();
|
||||
if (key.contains(clsName)) {
|
||||
IReceiver receiver = mReceivers.get(key);
|
||||
receiver.removeSchedulerListener();
|
||||
receiver.unRegister();
|
||||
receiver.destroy();
|
||||
if (receiver != null) {
|
||||
receiver.removeSchedulerListener();
|
||||
receiver.unRegister();
|
||||
receiver.destroy();
|
||||
}
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
@@ -15,9 +15,12 @@
|
||||
*/
|
||||
package com.arialyy.aria.core;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Build;
|
||||
import android.os.Message;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.util.Log;
|
||||
import android.widget.PopupWindow;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
@@ -30,23 +33,45 @@ import java.lang.reflect.Field;
|
||||
final class WidgetLiftManager {
|
||||
private final String TAG = "WidgetLiftManager";
|
||||
|
||||
/**
|
||||
* 处理DialogFragment事件
|
||||
*
|
||||
* @param dialogFragment {@link android.app.DialogFragment}
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB) boolean handleDialogFragmentLift(
|
||||
android.app.DialogFragment dialogFragment) {
|
||||
return handleDialogLift(dialogFragment.getDialog());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理DialogFragment事件
|
||||
*
|
||||
* @param dialogFragment {@link android.support.v4.app.DialogFragment}
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB) boolean handleDialogFragmentLift(
|
||||
DialogFragment dialogFragment) {
|
||||
return handleDialogLift(dialogFragment.getDialog());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理悬浮框取消或dismiss事件
|
||||
*/
|
||||
void handlePopupWindowLift(PopupWindow popupWindow) {
|
||||
boolean handlePopupWindowLift(PopupWindow popupWindow) {
|
||||
try {
|
||||
Field dismissField = CommonUtil.getField(popupWindow.getClass(), "mOnDismissListener");
|
||||
PopupWindow.OnDismissListener listener =
|
||||
(PopupWindow.OnDismissListener) dismissField.get(popupWindow);
|
||||
if (listener != null) {
|
||||
Log.e(TAG, "你已经对PopupWindow设置了Dismiss事件。为了防止内存泄露,"
|
||||
+ "请在dismiss方法中调用Aria.download(this).removeSchedulerListener();来注销事件");
|
||||
+ "请在dismiss方法中调用Aria.download(this).unRegister();来注销事件");
|
||||
return true;
|
||||
} else {
|
||||
popupWindow.setOnDismissListener(createPopupWindowListener(popupWindow));
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +88,7 @@ final class WidgetLiftManager {
|
||||
/**
|
||||
* 处理对话框取消或dismiss
|
||||
*/
|
||||
void handleDialogLift(Dialog dialog) {
|
||||
boolean handleDialogLift(Dialog dialog) {
|
||||
try {
|
||||
Field dismissField = CommonUtil.getField(dialog.getClass(), "mDismissMessage");
|
||||
Message dismissMsg = (Message) dismissField.get(dialog);
|
||||
@@ -72,8 +97,10 @@ final class WidgetLiftManager {
|
||||
Field cancelField = CommonUtil.getField(dialog.getClass(), "mCancelMessage");
|
||||
Message cancelMsg = (Message) cancelField.get(dialog);
|
||||
if (cancelMsg != null) {
|
||||
Log.e(TAG, "你已经对Dialog设置了Dismiss和cancel事件。为了防止内存泄露,"
|
||||
+ "请在dismiss方法中调用Aria.download(this).removeSchedulerListener();来注销事件");
|
||||
Log.e(TAG, "你已经对Dialog设置了Dismiss和cancel事件。"
|
||||
+ "为了防止内存泄露,请在dismiss方法中调用Aria.download(this).unRegister();来注销事件\n"
|
||||
+ "如果你使用的是DialogFragment,那么你需要在onDestroy()中进行销毁Aria事件操作");
|
||||
return true;
|
||||
} else {
|
||||
dialog.setOnCancelListener(createCancelListener());
|
||||
}
|
||||
@@ -83,6 +110,7 @@ final class WidgetLiftManager {
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -16,6 +16,7 @@
|
||||
package com.arialyy.aria.core.download;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.inf.AbsEntity;
|
||||
import com.arialyy.aria.core.inf.AbsReceiver;
|
||||
@@ -128,6 +129,9 @@ public class DownloadReceiver extends AbsReceiver {
|
||||
if (dgCounter != null && dgCounter.contains(className)) {
|
||||
DownloadGroupSchedulers.getInstance().unRegister(obj);
|
||||
}
|
||||
if (needRmReceiver) {
|
||||
AriaManager.getInstance(AriaManager.APP).removeReceiver(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,8 +167,7 @@ public class DownloadReceiver extends AbsReceiver {
|
||||
*/
|
||||
public DownloadEntity getDownloadEntity(String downloadUrl) {
|
||||
CheckUtil.checkDownloadUrl(downloadUrl);
|
||||
return DbEntity.findFirst(DownloadEntity.class, "url=? and isGroupChild='false'",
|
||||
downloadUrl);
|
||||
return DbEntity.findFirst(DownloadEntity.class, "url=? and isGroupChild='false'", downloadUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -20,8 +20,11 @@ package com.arialyy.aria.core.inf;
|
||||
* Created by AriaL on 2017/6/27.
|
||||
*/
|
||||
|
||||
public abstract class AbsReceiver<ENTITY extends AbsEntity> implements IReceiver<ENTITY>{
|
||||
public abstract class AbsReceiver<ENTITY extends AbsEntity> implements IReceiver<ENTITY> {
|
||||
public String targetName;
|
||||
public Object obj;
|
||||
|
||||
/**
|
||||
* 当dialog、dialogFragment、popupwindow已经被设置了关闭监听时,需要手动移除receiver
|
||||
*/
|
||||
public boolean needRmReceiver = false;
|
||||
}
|
||||
|
@@ -146,5 +146,8 @@ public class UploadReceiver extends AbsReceiver<UploadEntity> {
|
||||
if (dCounter != null && dCounter.contains(className)) {
|
||||
UploadSchedulers.getInstance().unRegister(obj);
|
||||
}
|
||||
if (needRmReceiver) {
|
||||
AriaManager.getInstance(AriaManager.APP).removeReceiver(obj);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user