0

長名稱的道歉。我的問題如下所示:我使用DialogFragment來防止AlertDialogs在輪換時被解散(類似於這裏的答案:Prevent dialog dismissal on screen rotation in Android)。防止ProgressDialog在輪換時被解僱,但仍允許從AsyncTask解僱

現在,我在後臺運行一些任務,可能需要幾秒鐘。我想展示一個progressdialog來告訴用戶發生了什麼。任務完成後,ProgressDialog應該從AsyncTask中的完成方法中解除。

就像上面的鏈接,我使用DialogFragment創建一個對話框。該對話框保持旋轉狀態(這很好)。然而,一旦我的任務完成並且屏幕旋轉了,我不能關閉對話框。

這裏是我已經試過策略(這兩種方法工作,如果屏幕不旋轉):「()駁回」的DialogFragment的

  • 調用。屏幕旋轉後,這會導致崩潰 java.lang.NullPointerException:試圖調用虛擬方法'android.app.FragmentTransaction android.app.FragmentManager.beginTransaction()'null對象引用 android.app.DialogFragment.dismissInternal DialogFragment.java:296) android.app.DialogFragment.dismiss(DialogFragment.java:267)
  • 調用一些內部方法調用「getDialog()。dismiss()」:getDialog()返回始終爲空(旋轉後)儘管顯示對話框。

有人能帶我進入正確的方向嗎?

編輯:下面是一些代碼

活動裏面,我只需創建一個TaskFragment,做一些背景工作:

public class MainActivity extends AppCompatActivity { 

    private TaskFragment ft; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     ft = (TaskFragment) getFragmentManager().findFragmentByTag("task"); 

     if(ft == null) { 
      // create new 
      ft = TaskFragment.newInstance(); 

      FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
      transaction.add(ft, "task"); 
      transaction.commit(); 
     } 
    } 
} 

的TaskFragment我在裏面運行的AsyncTask。在onPreExecute我顯示ProgressDialog,在onPostExecute我駁回:

public class TaskFragment extends Fragment { 

    public static TaskFragment newInstance() { 
     return new TaskFragment(); 
    } 

    public TaskFragment() {} 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     this.setRetainInstance(true); 

     // Run a background task and show a dialog 
     new AsyncTask<Void, Void, Void>() { 
      MyDialogFragment ft; 

      @Override 
      protected void onPreExecute() { 
       // show progress dialog 
       ft = MyDialogFragment.newInstance(); 
       ft.show(getActivity().getFragmentManager(), "dialog"); 
      } 

      @Override 
      protected Void doInBackground(Void...params) { 
       try { 
        // Do some work... 
        Thread.sleep(5000); 
       } catch (InterruptedException ignored) {} 

       return null; 
      } 

      @Override 
      protected void onPostExecute(Void p) { 
       // remove progress dialog 
       ft.dismiss(); 
      } 
     }.execute(); 
    } 
} 

的DialogFragment只是以下幾點:

public class MyDialogFragment extends DialogFragment { 
    public static MyDialogFragment newInstance() { 
     MyDialogFragment fragment = new MyDialogFragment(); 
     return fragment; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setCancelable(false); 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     ProgressDialog dialog = new ProgressDialog(getActivity()); 

     dialog.setIndeterminate(true); 

     dialog.setTitle("Hello World"); 

     return dialog; 
    } 
} 

感謝和問候, 卡爾

+1

最小代碼在哪裏? ... – Selvin

+0

無論如何:https://gist.github.com/SelvinPL/4230c0b6b45fb69a8ed856a4fa43dec3 – Selvin

+0

只需添加最少的代碼。感謝代碼,我認爲它指向了正確的方向(我認爲DialogFragments保留,不會在循環後重新創建)。會檢查。謝謝(對不起,最初不添加最小代碼示例 – Searles

回答

0

感謝Selvin,你的代碼評論指出我正確的方向。

問題是,當我解僱它時,我不得不重新抓取碎片。此外,由於當對話框被解除時,活動可能不會被激活,所以當我解僱它時避免NullPointerException,我需要允許stateloss。因此,我更新AsyncTask到以下,它工作正常。

 // Run a background task and show a dialog 
    new AsyncTask<Void, Void, Void>() { 
     @Override 
     protected void onPreExecute() { 
      // show progress dialog 
      MyDialogFragment ft = MyDialogFragment.newInstance(); 
      ft.show(getActivity().getFragmentManager(), "dialog"); 
     } 

     @Override 
     protected Void doInBackground(Void...params) { 
      try { 
       // Do some work... 
       Thread.sleep(5000); 
      } catch (InterruptedException ignored) {} 

      return null; 
     } 

     @Override 
     protected void onPostExecute(Void p) { 
      MyDialogFragment ft = 
       (MyDialogFragment) getFragmentManager() 
       .findFragmentByTag("dialog"); 

      // remove progress dialog 
      ft.dismissAllowingStateloss(); 
     } 
    }.execute(); 

再次感謝您的幫助。