Android 对已销毁的活动调用finish()时会发生什么情况?
在查看一些现有的活动代码时,我意识到一些截取异步网络响应处理程序调用Android 对已销毁的活动调用finish()时会发生什么情况?,android,android-activity,android-volley,android-lifecycle,Android,Android Activity,Android Volley,Android Lifecycle,在查看一些现有的活动代码时,我意识到一些截取异步网络响应处理程序调用finish()返回给调用者(调用者通常通过startActivityForResult启动我的活动)。大概是这样的: private Response.Listener<MyResponse> mResponseListener = new Response.Listener<MyResponse>(){ @Override public void onResponse(MyResponse m
finish()
返回给调用者(调用者通常通过startActivityForResult
启动我的活动)。大概是这样的:
private Response.Listener<MyResponse> mResponseListener = new Response.Listener<MyResponse>(){
@Override public void onResponse(MyResponse myResponse) {
// I could get here *after* rotation was initiated
// do stuff
finish();
};
}
private Response.Listener mResponseListener=new Response.Listener(){
@覆盖公共void onResponse(MyResponse MyResponse){
//我可以在轮换开始后到这里
//做事
完成();
};
}
在最近对一个bug进行了一些调查之后,我意识到我的代码没有正确处理旋转情况——理论上,当设备旋转时,网络响应处理程序可以在活动实例A1的销毁和活动实例A2的创建之间调用。调用A1的onDestroy
后调用finish()
有什么影响?“我们完蛋了”这一事实是真的吗?A2是否会被创建并像从未调用过finish
一样一直保持
调用A1的onDestroy后调用finish()有什么影响
我不确定,但在我看来,它应该完成活动并将其从任务的后堆栈中移除
我认为你的问题的根源在别处,尽管-活动和片段确实不是处理网络或其他异步操作的合适位置。在MVC或MVP设计中,您应该更像对待哑视图一样对待活动和片段-它们应该接受来自控制器的一些数据,并相应地呈现它们的视图
因此,发出异步请求的合适位置应该是一个普通Java类,其实例保存在应用程序
上下文中,而不是任何活动
上下文中。这样,执行异步操作的对象就不会绑定到易变的活动/片段生命周期
例如,我喜欢使用带有跨线程粘性事件的EventBus
在发出请求的对象和必须显示结果的活动之间进行通信,在活动的onResume
回调中订阅事件侦听器,并在onPause
中取消订阅
这篇文章极大地帮助我学会思考活动和片段
调用A1的onDestroy后调用finish()有什么影响
我不确定,但在我看来,它应该完成活动并将其从任务的后堆栈中移除
我认为你的问题的根源在别处,尽管-活动和片段确实不是处理网络或其他异步操作的合适位置。在MVC或MVP设计中,您应该更像对待哑视图一样对待活动和片段-它们应该接受来自控制器的一些数据,并相应地呈现它们的视图
因此,发出异步请求的合适位置应该是一个普通Java类,其实例保存在应用程序
上下文中,而不是任何活动
上下文中。这样,执行异步操作的对象就不会绑定到易变的活动/片段生命周期
例如,我喜欢使用带有跨线程粘性事件的EventBus
在发出请求的对象和必须显示结果的活动之间进行通信,在活动的onResume
回调中订阅事件侦听器,并在onPause
中取消订阅
一篇对我学习思考活动和片段有很大帮助的文章是。我相信onDestroy之后发生的事情是,活动已经到了生命周期的尽头,很快就会被垃圾收集 我可以为你的案子想出两个解决办法
公共静态类ResponseEvent{
我的反应我的反应;
公共响应事件(MyResponse MyResponse){
this.myResponse=myResponse;
}
}
public void onCreate(){
BusProvider.getInstance().register(this);//将此活动注册为订阅服务器
}
公共空间{
BusProvider.getInstance().unregister(此);
}
//注册和注销的位置取决于您自己
//当活动启动时,是否要消化响应
//也在前景或背景上。
private Response.Listener mResponseListener=new Response.Listener(){
@覆盖公共void onResponse(MyResponse MyResponse){
//我可以在轮换开始后到这里
//做事
BusProvider.getInstance().post(新响应事件(myResponse));
//将此事件发送到以前注册的子服务器。
//订阅服务器方法将一直处于活动状态
//还没有注销。
//调用unregister后不会发生任何事情。
}};
//这是将消化您的响应的订户方法
@改编
公共无效事件响应(响应事件){
//在这里用回应做你的事情。
完成();
//请注意,我将finish()移到了这里,以便您可以确定
//只有在活动仍处于活动状态时才会调用它
}
我相信onDestroy之后发生的事情是,该活动到达其生命周期的末尾,很快就会被垃圾回收
我可以为你的案子想出两个解决办法
public static class ResponseEvent{
MyResponse myResponse;
public ResponseEvent(MyResponse myResponse){
this.myResponse = myResponse;
}
}
public void onCreate(){
BusProvider.getInstance().register(this);// register this activity as subscriber
}
public void onDestroy(){
BusProvider.getInstance().unregister(this);
}
// it is up you where you want to register and unregister depending
// whether you want to digest the response when the activity
// is on foreground or background as well.
private Response.Listener<MyResponse> mResponseListener = new Response.Listener<MyResponse>(){
@Override public void onResponse(MyResponse myResponse) {
// I could get here *after* rotation was initiated
// do stuff
BusProvider.getInstance().post(new ResponseEvent(myResponse));
//sends this event to previously registered subcsriber.
//The subscriber method will be active as long the activity
//hasn't been de-registered.
//Nothing will happen after unregister has been called.
}};
//this is the subscriber method that will digest your response
@Subsribe
public void onGotResponse(ResponseEvent event){
// do your stuff with response here.
finish();
// notice I moved finish() here so you can be sure
// it will only be called as long as the activity is still active
}