Thank you a lot!
Just setting setRetainInstance(true) in DialogFragment is not enough. The
dialog just disappears after rotation.
I happen to find a thread:
http://stackoverflow.com/questions/8235080/fragments-dialogfragment-and-screen-rotation
In addition to setRetainInstance(true), we should override

@Override
public void onDestroyView() {
  if (getDialog() != null && getRetainInstance())
    getDialog().setOnDismissListener(null);
  super.onDestroyView();
}

and it works!

However, it is very strange that "IllegalStateException: Can't retain
fragements that are nested in other fragments" does not occur.
ProgressDialog fragment is in fragmentA. It is nested.


2013/9/15 Piren <gpi...@gmail.com>

> err, actually i've also missed something and read the stacktrace
> incorrectly. Only now i've noticed the NPE was actually in the framework
> code...
> If you didn't already, add SetRetainInstance to the DialogFragment as well
> (in its onCreate, not onCreateDialog).
> as a last resort you can always override onDismiss and avoid calling the
> base class (you should probably still call the Fragment.Dissmiss method and
> handle the BackStack on your own)
>
>
>
>
> On Sunday, September 15, 2013 3:25:41 PM UTC+3, Greenhand wrote:
>>
>> Yes. I am pretty sorry for my carelessness when extracting the related
>> code snippets.
>> new MyAsyncTask.execute() should be new MyAsyncTask(this).execute().
>>
>> As for the MyAsyncTask:
>>
>> public class MyAsyncTask extends AsyncTask<Void,Void,Void>{ //do network
>> operation
>>  private Fragment*A* fragment;
>>
>>  public MyAsyncTask(Fragment*A* fragmentA){
>>   fragment = fragmentA;
>>  }
>> If there is any mistake, please feel free to correct me.
>>
>>
>> Piren於 2013年9月15日星期日UTC+**8下午8時08分31秒寫道:
>>
>>> and did you use that constructor? because the code snippet shows you've
>>> used the default constructor
>>>
>>> On Sunday, September 15, 2013 1:52:22 PM UTC+3, Greenhand wrote:
>>>>
>>>> Thanks for pointing out the mistakes. The whole code is too long to
>>>> post and maintain readability so I just put some snippet. The "MyAsyncTask
>>>>  having a constructor named GetTokenAsyncTask" is  a typo, the constructor
>>>> should named MyAsyncTask.
>>>> As for ProgressFragment, I use its toString() method to check using
>>>> Log.d(). They are the same across rotation.
>>>>
>>>>
>>>>
>>>> 2013/9/15 Piren <gpi...@gmail.com>
>>>>
>>>>> It's hard to follow your code since it seems some of it is incorrect
>>>>> (like  MyAsyncTask   having a constructor named GetTokenAsyncTask) and 
>>>>> some
>>>>> of it is missing...
>>>>> Either way you should verify you actually used that constructor (in
>>>>> the current code you don't, so the member "fragment" is null).Either case,
>>>>> you should also verify that the proper ProgressFragment is being set 
>>>>> during
>>>>> onAttach of FragmentA since i assume a new one will be created after
>>>>> rotation (though i'm not sure about that).
>>>>>
>>>>> Since this isn't that much code, you should probably just find a
>>>>> tutorial on how to do that (there's a lot of those online) and start from
>>>>> scratch (just so you wouldn't miss something)
>>>>>
>>>>> On Sunday, September 15, 2013 1:30:20 PM UTC+3, Greenhand wrote:
>>>>>>
>>>>>> I use appcompat library to host some fragments for tabs. In a
>>>>>> specific fragment A, I need to do network operation. In order not to 
>>>>>> block
>>>>>> the UI thread, I use an AsyncTask and do the network operation in
>>>>>> doInBackGround().
>>>>>>
>>>>>> To prevent messing around keep AsyncTask to survive rotation in the
>>>>>> fragment, I call setRetainInstance(true) in the fragment A oncreate().
>>>>>>
>>>>>> It works fine but I need to prompt user something when the network
>>>>>> operation is in progress. Therefore, I use DialogFragment. In the
>>>>>> DialogFragment onCreateView(), it instantiates a ProgressDialog and 
>>>>>> returns.
>>>>>>
>>>>>> To be concrete, the following is the code snippets of FragmentA,
>>>>>> MyDialogFragment and AsyncTask :
>>>>>> public class FragmentA extends Fragment{ //as tab for actionbar
>>>>>> (appcompat)
>>>>>>  private boolean isNetworkOperationCalled;
>>>>>>  private MyDialogFragment myDialogFragment;
>>>>>>  ...
>>>>>>  public void showProgressDialog(){ //for MyAsyncTask#onPreExecute()
>>>>>>   myDialogFragment = new MyDialogFragment();
>>>>>>   myDialogFragment.show(**getFra**gmentManager(), "mydialog");
>>>>>>  }
>>>>>>  public void showProgressDialog(){ //for MyAsyncTask#onPostExecute()
>>>>>>   myDialogFragment.dismiss();
>>>>>>  }
>>>>>>  public void onResume() {
>>>>>>   if(!**isNetworkOperationCalled**){
>>>>>>    isNetworkOperationCalled=true;
>>>>>>    new MyAsyncTask.execute();//do the network operation
>>>>>>   }
>>>>>>  }
>>>>>>  ...
>>>>>> }
>>>>>>
>>>>>>
>>>>>> public class MyDialogFragment extends DialogFragment{
>>>>>> //ProgressDialog for FragmentA
>>>>>>  ...
>>>>>>  public Dialog onCreateDialog(Bundle savedInstanceState) {
>>>>>>   ProgressDialog progressDialog = new ProgressDialog(getActivity(),**
>>>>>> P**rogressDialog.STYLE_SPINNER);
>>>>>>   ... //set the dialog attributes
>>>>>>   return progressDialog;
>>>>>>  }
>>>>>>  ...
>>>>>> }
>>>>>> public class MyAsyncTask extends AsyncTask<Void,Void,Void>{ //do
>>>>>> network operation
>>>>>>  private Fragment fragment;
>>>>>>
>>>>>>  public GetTokenAsyncTask(Fragment fragmentA){
>>>>>>   fragment = fragmentA;
>>>>>>  }
>>>>>>  protected void onPreExecute() {
>>>>>>   fragment.showProgressDialog(****); //show progess dialog for users
>>>>>>  }
>>>>>>  protected String doInBackground(Void... arg0) {
>>>>>>   ...
>>>>>>  }
>>>>>>  protected void onPostExecute() { //dismiss the dialog
>>>>>>   fragment.**dismissProgressDial**og();
>>>>>>  }
>>>>>> }
>>>>>> In a nutshell, fragment A triggers AsyncTask and AsyncTask call
>>>>>> methods of FragmentA to show/dismiss dialog. Fragment A use
>>>>>> MyDialogFragment to show the progress dialog.
>>>>>>
>>>>>> The code (method) above works if there is no rotataion occurs while
>>>>>> doInBackground() is executing. Nevertheless, if the rotation happens 
>>>>>> before
>>>>>> onPostExecute() is called,
>>>>>> the rotation is fine and the progress dialog is retained. Sadly, it
>>>>>> crashes when onPostExecute() finally be called when dismissing the 
>>>>>> dialog.
>>>>>>
>>>>>> E/AndroidRuntime(27493): FATAL EXCEPTION: main
>>>>>> E/AndroidRuntime(27493): java.lang.NullPointerException
>>>>>> E/AndroidRuntime(27493):  at android.support.v4.app.**DialogF**
>>>>>> ragment.**dismissInternal(**Dialog**Fragment.java:184)
>>>>>> E/AndroidRuntime(27493):  at android.support.v4.app.**DialogF**
>>>>>> ragment.dismiss(**DialogFragment**.java:155)
>>>>>> E/AndroidRuntime(27493):  at com.example.FragmentA.**dismissP**
>>>>>> rogressDialog(**FragmentA.java:**105)
>>>>>> E/AndroidRuntime(27493):  at com.example.FragmentA.access$**1**
>>>>>> (FragmentA.java:103)
>>>>>> E/AndroidRuntime(27493):  at com.example.FragmentA$**GetToken**
>>>>>> AsyncTask.**onPostExecute(**FragmentA.java:**40)
>>>>>> E/AndroidRuntime(27493):  at com.example.FragmentA$**GetToken**
>>>>>> AsyncTask.**onPostExecute(**FragmentA.java:**1)
>>>>>> E/AndroidRuntime(27493):  at android.os.AsyncTask.finish(**As**
>>>>>> yncTask.java:631)
>>>>>> E/AndroidRuntime(27493):  at android.os.AsyncTask.access$**60**
>>>>>> 0(AsyncTask.java:177)
>>>>>> E/AndroidRuntime(27493):  at android.os.AsyncTask$**InternalH**
>>>>>> andler.handleMessage(**AsyncTask**.java:644)
>>>>>> E/AndroidRuntime(27493):  at android.os.Handler.**dispatchMes**
>>>>>> sage(Handler.java:**99)
>>>>>> E/AndroidRuntime(27493):  at android.os.Looper.loop(Looper.****
>>>>>> java:137)
>>>>>> E/AndroidRuntime(27493):  at android.app.ActivityThread.**mai**
>>>>>> n(ActivityThread.java:4875)
>>>>>> E/AndroidRuntime(27493):  at 
>>>>>> java.lang.reflect.Method.**invok**eNative(Native
>>>>>> Method)
>>>>>> E/AndroidRuntime(27493):  at java.lang.reflect.Method.**invok**
>>>>>> e(Method.java:511)
>>>>>> E/AndroidRuntime(27493):  at com.android.internal.os.**Zygote**Init$*
>>>>>> *MethodAndArgsCaller.run(**Z**ygoteInit.java:804)
>>>>>> E/AndroidRuntime(27493):  at com.android.internal.os.**Zygote**
>>>>>> Init.main(ZygoteInit.**java:571)
>>>>>> E/AndroidRuntime(27493):  at dalvik.system.NativeStart.**main**(Native
>>>>>> Method)
>>>>>>
>>>>>> How can I solve the problem so that the dialog can dismiss correctly
>>>>>> after rotation?
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>  --
> You received this message because you are subscribed to the Google
> Groups "Android Developers" group.
> To post to this group, send email to android-developers@googlegroups.com
> To unsubscribe from this group, send email to
> android-developers+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/android-developers?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Android Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to android-developers+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to android-developers+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to