AvoidOnResult icon indicating copy to clipboard operation
AvoidOnResult copied to clipboard

Activity被回收后Callback不会回调

Open JasonCheng213 opened this issue 7 years ago • 11 comments

Activity被回收后Fragment重建callback队列被重建清空,不能回调

JasonCheng213 avatar Aug 22 '18 08:08 JasonCheng213

setRetainInstance调用了,fragment不会被清空把?

sola1tmy avatar Sep 07 '18 02:09 sola1tmy

是会有这种问题的,但是一直没想到什么好办法

AnotherJack avatar Sep 07 '18 03:09 AnotherJack

是不是可以用static final修饰一下。试了一下mCallBack不会被回收。 然后因为hashCode都是各自内存地址,不同的activity应该也不会出现冲突的情况。 另外,这样一个application只会创建一个集合,也没必要担心没必要的内存占用

sola1tmy avatar Sep 09 '18 02:09 sola1tmy

我想到了一个方案,有空帮看看是否妥当: asiontang/YeAvoidOnResult

asiontang avatar Sep 12 '18 10:09 asiontang

@asiontang 你好,刚看了一下您的代码,是采用在Base类中收集所有的回调,然后在onActivityResult中根据requestCode分发回调,关于activity被回收的情况是在onSaveInstanceState把所有回调的classname存起来,在onRestore中再把classname取出来,通过反射创建回调对象进行恢复,整体的思路应该是这样的。是个很不错的思路,但是有一点,我看反射创建listener的时候使用的是带有外部Activity的一个参数的构造器,如果没猜错的话这个构造器的存在是因为内部类持有外部类的引用吧,那如果我创建listener的代码是在点击事件中,在OnClickListener中,是不是这个构造器的参数类型就不是外部Activity而是OnClickListener了,所以我觉得这一点有待考究。

再抛开以上这种情况,我觉得只是把当前的activity传进去也是不够的,考虑一种情况,有一个列表页面,分页加载的,有个全局的List存着列表的数据,比如已经加载了100条了,我点击第100条想startForResult获取一些数据,回来的时候还要用到这第100条数据,按您现在的代码的话,回来的时候页面应该只加载了第一页,可能这时候这个list并没有第100条数据,可能就出错了。当然,可以在onSaveIns的时候把这个list也存储上,onRestore的时候再恢复,应该就可以了,也就是说需要把listener中用到的数据都存起来。我觉得按您的思路再完善完善,应该可以尝试一下的。

AnotherJack avatar Sep 12 '18 11:09 AnotherJack

@AnotherJack 按照您提出来的建议,写了测试代码实际验证后发现的确存在问题, 我在项目 Readme 里增加了错误的示范代码和正确的示范代码. 有空可再帮瞧瞧是否有不妥.

asiontang avatar Sep 13 '18 07:09 asiontang

对之前的listener 上下文不好确定,@asiontang 的方案太过局限了

guofeng007 avatar Sep 25 '18 02:09 guofeng007

是不是可以用static final修饰一下。试了一下mCallBack不会被回收。 然后因为hashCode都是各自内存地址,不同的activity应该也不会出现冲突的情况。 另外,这样一个application只会创建一个集合,也没必要担心没必要的内存占用

我觉得这样,可以的;@sola1tmy

Alex-Cin avatar Dec 26 '18 06:12 Alex-Cin

问题:Activity被回收后Fragment重建callback队列被重建清空,不能回调 请问这个问题解决了吗,谢谢

OneGreenHand avatar Mar 25 '19 07:03 OneGreenHand

匿名内部类不可取, 所有的匿名内部类如果调用activity中的方法都会持有一个引用 如果是activity,该匿名内部类不回收的话,那么activity就会内存泄漏,

参考 Handle 内存泄漏

如果非要保存这个的话,应该是作为一个静态内部类实现/或者独立的类,将activity传过去,弱引用,

看是不是变得好复杂,写起来并不顺手,

当这个东西越来越复杂的时候,是不是该考虑这种处理方式是否合理

编译时注解,asm 可以再优化一下,但是真的好吗=.=

yizems avatar Aug 15 '19 05:08 yizems

看了上面的各类回复,我想请教下,除了 activity 被回收外,还有进程被回收的情况,这种情况似乎除了官方的 startActivityForResult 和 Activity Result,就没办法了吧?

imyyq-star avatar Dec 13 '21 07:12 imyyq-star