Volley resopnse处理程序在方向更改后解除对话框片段

时间:2016-06-25 08:13:07

标签: android android-fragments android-activity orientation android-volley

当我的Activity发出Volley请求时,我会显示一个包含对话框片段的对话框。在响应处理程序中,它是Activity的非静态内部类,我用以下方法忽略对话框片段:

@Override
public void onResponse(String response) {
    MyActivity.this.takeAwayTheDialog();
}

除非我旋转设备,否则工作正常。如果在方向更改完成后回复,则MyActivity.this已被销毁。

可能的解决方案包括:

  1. 在方向更改前取消请求
  2. 使用单独的保留片段来处理网络请求
  3. 但他们看起来并不令人满意。我希望有一个解决方案,允许系统为我处理方向,以便重新创建活动并加载正确的资源。任何人都可以评论上述两种解决方案或提出其他建议吗? THX。

1 个答案:

答案 0 :(得分:0)

既然没有人回答这个问题,我会在你的解决方案中写下我的意见:

  1. 在方向更改之前取消请求(可能在您的活动的onPause()中)并在方向更改后重新启动它(可能在onResume()中)可以是一个快速解决方案,但它可能会让你两次向服务器发送请求。

    这通常不是问题,但如果请求是POST请求,例如签署用户,则可能导致用户在方向更改后得到用户名已存在的错误(从第一个活动已成功将其签名到服务器,第二个活动正试图再次签署他/她。

    如果发送请求两次对你来说不是问题,这个解决方案很安静,因为Volley可以透明地缓存第一个请求的响应(如果服务器发送正确的头),第二个请求将获得响应好像你有一个超快的连接。 。

  2. 使用保留的无头片段,从其中启动Volley请求,并对当前活动进行回调工作非常好,我认为它确实允许系统为您处理方向以便重新创建活动并加载正确的资源,然后当前活动获取响应并将其显示给用户。

    我在这个解决方案中唯一能想到的缺点是需要编写很多样板代码,以下是如何使用这种方法显示对话框并隐藏它。

    public class MainActivity extends AppCompatActivity{
    
        public static class MainActivityHeadlessFragment extends Fragment {
    
            private MainActivity mActivity;
            public MainActivityHeadlessFragment() {
                // Required empty public constructor
            }
    
    
    
            @Override
            public void onCreate(@Nullable Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setRetainInstance(true);
            }
    
            public void ShowDialog() {
                DialogFragment newFragment = SampleDialogFragment.newInstance();
                newFragment.show(mActivity.getSupportFragmentManager(), "sample_dialog_tag");
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        Fragment f = mActivity.getSupportFragmentManager().findFragmentByTag("sample_dialog_tag");
                        if(f!= null){
                            DialogFragment df = (DialogFragment) f;
                            df.dismiss();
                        }
                    }
                }, 5000);
            }
    
            @Override
            public void onAttach(Context context) {
                super.onAttach(context);
                if (context instanceof MainActivity) {
                    mActivity= (MainActivity) context;
                } else {
                    throw new RuntimeException(context.toString()
                            + " MainActivityHeadlessFragment can only be used with MainActivity");
                }
            }
    
            @Override
            public void onDetach() {
                super.onDetach();
                mActivity= null;
            }
        }
    
        private MainActivityHeadlessFragment mDataFragment;
        private MainFragment mFragment;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            FragmentManager fm = getSupportFragmentManager();
            mDataFragment = (MainActivityHeadlessFragment) fm.findFragmentByTag("data_fragment");
    
            // If the Fragment is non-null, then it is currently being
            // retained across a configuration change.
            if (mDataFragment == null) {
                mDataFragment = new MainActivityHeadlessFragment();
                fm.beginTransaction().add(mDataFragment, "data_fragment").commit();
            }
        }
    
    
    
        public void ShowDialog(View v){
            mDataFragment.ShowDialog();
        }
    }
    

    为简单起见,我用new Handler().postDelayed()取代了Volley请求,但这个想法应该是一样的。 。