考虑一下这个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;
}
}
它只是一个带有处理程序的水平进度条,一旦处理程序收到一条消息,进度条从0变为100。
如果我想从活动中自己触发sendEmptyMessage,我总是获得空指针异常:
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的行;该应用运行。这个调用出了什么问题?
请注意,除了清单和布局文件之外,这是整个代码。
答案 0 :(得分:1)
NullPointerException
出现,因为findFragmentByTag
返回null
。解决方案是在使用fm.executePendingTransactions()
方法立即执行该片段事务(see this question for more details)之前调用findFragmentByTag
。
此外,Handler
引用此时将为null
,因此您需要在片段的一个生命周期方法中对其进行初始化,例如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);
}
}
};
}