0

この DialogFragment を考えてみましょう:

public class RollTriggerDialog extends DialogFragment{

    private ProgressDialog _dialog;
    int _progress;
    public Handler _progressHandler;

    public RollTriggerDialog() {
        // empty
    }

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

        this.setStyle(STYLE_NO_TITLE, getTheme());
        _dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        _dialog.setProgress(0);

        _progressHandler = new Handler() {
            public void handleMessage(Message msg) {
                super.handleMessage(msg);

                if (_progress >= 100) {
                    _dialog.dismiss();
                } else {
                    _progress++;
                    _dialog.incrementProgressBy(1);
                    _progressHandler.sendEmptyMessageDelayed(0,100);
                }

            }
        };
        //_progressHandler.sendEmptyMessage(0); <- This uncommented would start the progress
        return _dialog;
    }
}

これは、ハンドラーを備えた単なる水平プログレスバーであり、ハンドラーが 1 つのメッセージを受信すると、プログレスバーは 0 から 100 まで変化します。

アクティビティから sendEmptyMessage を自分でトリガーしたい場合、常にNull Pointer Exceptionが発生します。

public class MainActivity extends FragmentActivity {

    private RollTriggerDialog mRollTriggerDialog;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fm = getSupportFragmentManager();
        mRollTriggerDialog = new RollTriggerDialog();
        mRollTriggerDialog.show(fm, "addDiceDialog_tag");
        ((RollTriggerDialog)fm.findFragmentByTag("addDiceDialog_tag"))._progressHandler.sendEmptyMessage(0); // <--- NPE HERE!
    }
}

dialogFragment で sendEmptyMessage の行がコメント解除され、メイン アクティビティの NPE の行がコメント化されている場合。アプリが実行されます。その呼び出しの何が問題になっていますか?

これは、マニフェスト ファイルとレイアウト ファイルを除くコード全体であることに注意してください。

4

1 に答える 1

1

が返さNullPointerExceptionれるため、が表示されます。解決策は、メソッドを使用してそのフラグメントトランザクションをすぐに実行する前に呼び出すことです(詳細については、この質問を参照してください)。findFragmentByTagnullfm.executePendingTransactions()findFragmentByTag

また、Handler参照はnullその時点で行われるため、フラグメントのライフサイクルメソッドの1つで初期化する必要があります。たとえば、onCreate次のようになります。

public static Handler _progressHandler; // should be made static

//...
@Override
public void onCreate(Bundle savedInstanceState) {       
    super.onCreate(savedInstanceState);
    _progressHandler = new Handler() {
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            if (_progress >= 100) {
                _dialog.dismiss();
            } else {
                _progress++;
                _dialog.incrementProgressBy(1);
                _progressHandler.sendEmptyMessageDelayed(0, 100);
            }

        }
    };
}
于 2012-10-09T11:49:11.707 に答える