0

考虑这个DialogFragment: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! 
    } 
} 

如果sendEmptyMessage的线在dialogFrag注释掉并在主要活动中与NPE划界线进行评论;该应用程序运行。该调用有什么问题?

请注意,这是整个代码,除了清单和布局文件。

+0

嗯,看来这确实是棘手。有趣的是,我没有得到一个单一的投票 – quinestor

回答

1

出现NullPointerException是因为findFragmentByTag返回null。解决方法是在使用findFragmentByTag方法立即执行该片段事务之前调用fm.executePendingTransactions()see this question for more details)。

此外,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); 
      } 

     } 
    }; 
} 
+0

谢谢Luksprog,我今晚会检查这项工作。现在关于处理程序:你的意思是在OnCreate而不是onCreateDialog中初始化它,就像我在我的问题中做的那样?作为一个方面说明,我认为你的声明会给出一个编译器错误,因为处理器使用的是非静态的参考,比如_dialog – quinestor

+1

@quinestor你必须初始化处理器参考,因为'onCreateDialog'将在**之后被调用** Activity的'onCreate'方法(所以你会有一个null处理器引用,直到那时)。如果你将handler Handler类的实例初始化为一个字段,那么你需要将其余的字段声明为static。但是,当你在一个非静态方法中初始化处理器引用时,你几乎可以保证在你使用该方法时正确地初始化这些字段。我不太确定,所以你需要测试它。 – Luksprog

+0

是的Luksprog,就是这样。两者都将初始化移动到onCreate和executePndingTransactions(),我看到我必须详细阅读。 +1全部:) 关于静态处理程序,这是另一个问题,我想我会管理 – quinestor