2014-12-14 15 views
5

Ai đó có thể trả lời câu hỏi này cho tôi:Trạng thái hoạt động Android Mất nhà nước

Cho mục đích thử nghiệm Tôi đã tạo một hoạt động với vòng lặp mà tôi đang tạo 10 AlertDialogs hoặc 10 DialogFragments. Ngay sau khi bắt đầu hoạt động, tôi nhấn nút Home để gửi ứng dụng dưới nền. Nếu tôi chạy phương pháp ShowDialog() để tạo ra các DialogFragments ứng dụng sẽ sụp đổ với: Hành vi

IllegalStateException: Can not perform this action after onSaveInstanceState 

này được mong đợi.

Nhưng nếu tôi chạy phương thức showAlert() để tạo AlertDialogs và giống như trước khi tôi gửi ứng dụng đến nền ứng dụng không bị lỗi. Khi tôi trở lại hoạt động, tôi có thể thấy tất cả 10 AlertDialogs.

Câu hỏi đặt ra là tại sao trạng thái mất hoạt động xảy ra với DialogFragment chứ không phải với AlertDialog?

Tôi vẫn đang thay đổi giao diện người dùng sau khi trạng thái của hoạt động đã được lưu. Nền tảng mà trên đó tôi đã thử nghiệm là Android 4.4.2

public class Main extends FragmentActivity 
{ 
    private FragmentActivity activity = this; 
    private MyAsynk myAsynk; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.layout_main); 

     myAsynk = new MyAsynk(); 
     myAsynk.execute(); 
    } 

    private class MyAsynk extends AsyncTask<Void, Void, Void> 
    { 
     private boolean run = false; 

     public MyAsynk() 
     { 
      run = true; 
     } 

     @Override 
     protected Void doInBackground(Void... params) 
     { 
      for(int i = 0; i < 10 && run; i++) 
      { 
       try 
       { 
        Thread.sleep(1000); 
       } 
       catch (InterruptedException e) 
       { 
        e.printStackTrace(); 
       } 

//    showAlert("loop " + i); 
       showDialog("loop " + i); 
      } 

      return null; 
     } 

     public void stop() 
     { 
      run = false; 
     } 
    } 


    @Override 
    public void onBackPressed() 
    { 
     super.onBackPressed(); 

     if(null != myAsynk) 
     { 
      myAsynk.stop(); 
      myAsynk = null; 
     } 
    } 


    private void showAlert(final String txt) 
    { 
     try 
     { 
      Main.this.runOnUiThread(new Runnable() 
      { 
       @Override 
       public void run() 
       { 
        new AlertDialog.Builder(activity).setMessage(txt) 
        .setPositiveButton("Ok", new DialogInterface.OnClickListener() 
        { 
         @Override 
         public void onClick(DialogInterface dialog, int which) 
         { 
          try 
          { 
           if(null != dialog) 
           { 
            dialog.dismiss(); 
           } 
          } 
          catch(Exception e) 
          { 
           e.printStackTrace(); 
          } 
         } 
        }) 
        .show(); 
       } 
      }); 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 


    private void showDialog(final String txt) 
    { 
     try 
     { 
      Main.this.runOnUiThread(new Runnable() 
      { 
       @Override 
       public void run() 
       { 
        MyDialogFragment newFragment = MyDialogFragment.newInstance(txt); 
        FragmentTransaction ft = Main.this.getSupportFragmentManager().beginTransaction(); 

        newFragment.show(ft, "newFragment"); 
       } 
      }); 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 
} 

MyDialogFragment.java:

public class MyDialogFragment extends DialogFragment 
{ 
    private MyDialogFragment instance; 

    public static MyDialogFragment newInstance(String text) 
    { 
     MyDialogFragment f = new MyDialogFragment(); 

     Bundle args = new Bundle(); 
     args.putString("text", text); 
     f.setArguments(args); 

     return f; 
    } 

    public MyDialogFragment() 
    { 
     instance = this; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
     View v = inflater.inflate(R.layout.my_dialog_fragment, container, false); 
     TextView tv = (TextView) v.findViewById(R.id.tv); 
     Button bu = (Button) v.findViewById(R.id.bu); 

     bu.setOnClickListener(new View.OnClickListener() 
     { 
      @Override 
      public void onClick(View v) 
      { 
       try 
       { 
        if(null != instance && instance.isVisible()) 
        { 
         instance.dismiss(); 
        } 
       } 
       catch(Exception e) 
       { 
        e.printStackTrace(); 
       } 
      } 
     }); 

     tv.setText(getArguments().getString("text")); 

     return v; 
    } 
} 

Trả lời

1

Câu trả lời rất đơn giản, mặc dù một chút underwhelming.

Trường hợp được thấy java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState ngoại lệ thực sự được ném bởi lớp FragmentManager. Lý do tại sao được giải thích rất tốt trong this post by Alex Lockwood.

DialogFragments là các mảnh vỡ (và do đó được quản lý bởi FragmentManager). Do đó, việc hiển thị các hộp thoại theo cách này có thể gây ra ngoại lệ. Tuy nhiên, việc thực hiện AlertDialog là hoàn toàn khác nhau: nó không sử dụng Fragments (tất cả, nó thực sự có trước Fragments). Do đó, không có ngoại lệ.

Các vấn đề liên quan