5

現在、DialogFragments に問題があります。私は最新の v.4 サポート パッケージ (リビジョン 8 だと思います) を使用しています。私の問題は、ダイアログが開いている間に電話の向きが変わると、アプリケーションがおかしくなり始めることです。

現在、私のアプリケーションは次のように動作します: FragmentActivity があり、Fragment を呼び出します。次に、この Fragment は DialogFragment を呼び出します (getActivity().getSupportFragmentManager() を介して)。

ダイアログが開いている間に向きが変わった場合、Fragment = null の getActivity()。アクティビティなどを終了したい場合、これは問題を引き起こします。

これを行うには、ダイアログを開き、方向を変更してボタンを押します。ボタンを押した後にのみクラッシュします

私の DialogFragment は AlertDialogFragment と呼ばれます:

public class AlertDialogFragment extends DialogFragment {
private static Builder mBuilder;
private static DialogInterface.OnClickListener mListener;

public static AlertDialogFragment newInstance(Context context, DialogInterface.OnClickListener listener) {
    mBuilder = new AlertDialog.Builder(context);
    mListener = listener;       
    return new AlertDialogFragment();
}

//... some functions to set Icons etc

public void setButton(int whichButton, CharSequence buttonText) {
    final DialogInterface.OnClickListener listener = mListener == null ? null : mListener;      
    mBuilder.setPositiveButton(buttonText, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                listener.onClick(dialog, whichButton);
            }
    });
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    return mBuilder.create();
}
}

これはフラグメントです:

public class TestBedFragment extends Fragment implements DialogInterface.OnClickListener   {
// onCreateView Stuff  

private void showCrashDialog() {
    FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
    AlertDialogFragment newDialog = AlertDialogFragment.newInstance(getActivity(), this);
    newDialog.setTitle("Test");     
    newDialog.setIcon(android.R.drawable.ic_dialog_alert);
    newDialog.setMessage("Testing testing testing... 1, 2, 3... Just press Ok.");
    newDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Ok");
    newDialog.show(ft, "dialog");

    // Cause the problem. Simulate the user turning the screen
    getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

@Override
public void onClick(DialogInterface dialog, int which) {

    /*
     * hexnumber = a hex number
     * Normally equals: TestBedFragment{hexnumber #0 id=hexnumber}
     * With crash equals: TestBedFragment{hexnumber}
     */
    Log.e("TestBedFragment", "this = " + this);

    /*
     * hexnumber = a hex number
     * Normally equals: com.example.TestBed.TestBedActivity@hexnumber
     * With crash equals: null
     */
    Log.e("TestBedFragment", "getActivity() = " + getActivity()); // Will equal null... ???

    getActivity().finish();
}
}

何が原因なのかよくわかりません。ばかげた質問でしたら申し訳ありません。「Windows Leaking」について他の場所で読んだことがありますが、logcat でそのようなことについて言及されているのを見たことがありません。

誰でも私を助けることができます:)それは大歓迎です

ありがとう

4

3 に答える 3

2

アクティビティのライフサイクルを理解する必要があります。デバイスを回転させるたびに、アクティビティが再作成されます。これは、クラスの新しいインスタンスが実行中であることを意味します。

コードで何が起こるかというと、ローテーションの後、リスナーは前のダイアログ インスタンスで getActivity を呼び出し、前のアクティビティを参照します。しかし、このアクティビティはもはや有効ではありません。ローテーション後に「破棄」され、新しいアクティビティが登場しました。

getActivity への呼び出しは無効になりました。

フラグメントの onDestroy メソッド中に開いているダイアログを閉じることはできませんか?

于 2012-05-11T00:25:36.093 に答える
0

onPause()でダイアログを閉じ、条件を使用してonCreate()でダイアログをチェックおよび表示()することができます。これは、特定のユースケースに応じて、onStop()またはonDestroy()でより適切な場合があります。

@Override
protected void onPause() {
    if (myDialog != null && myDialog.isVisible())
        myDialog .dismiss();
    super.onPause();
}
于 2012-08-07T22:12:52.180 に答える
0

バンドルを使用する代わりに、すべてを再作成しています。ifをonCreateDialog に追加して、null バンドルをチェックします。null の場合は作成作業を行います。それ以外の場合は何もせず、Android はバンドルからすべてを復元します。

これで問題が解決すると思います。

if(SavesIinstanceState == null); {
    // your code
}
于 2012-05-10T22:27:35.527 に答える