0

I know that this is not a serious question (and my code is not perfect...), but I wonder why after initialization of the field, which passed as a parameter to the method, the field has a null pointer (null)?

public class MainActivity extends ActionBarActivity{
private ProgressDialog prdialog;

    ProgressDialog prepareDialog(ProgressDialog pr){
        if (pr==null){
            pr=new ProgressDialog(this);
        }
        pr.setTitle(R.string.Download);
        pr.setCanceledOnTouchOutside(false);
        pr.setCancelable(false);
        pr.setMessage(getString(R.string.Wait_));
        return pr;
    }
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        prepareDialog(prdialog).show();
        //do some operations
        prdialog.dismiss();//here my app is crashes because prdialog=null
    }
}
Vladislav
  • 1,236
  • 13
  • 22

2 Answers2

2

Java only uses pass-by-value for parameters. See Is Java "pass-by-reference" or "pass-by-value"?

This means that the line

    prepareDialog(prdialog).show();

does not update the value of prdialog (and although it does produce a result, you're not assigning it to the prdialog member either) . Hence, it's null later. What you want to do is probably:

ProgressDialog prepareDialog() {
    ProgressDialog pr = new ProgressDialog(this);
    pr.setTitle(R.string.Download);
    pr.setCanceledOnTouchOutside(false);
    pr.setCancelable(false);
    pr.setMessage(getString(R.string.Wait_));
    return pr;
}

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    prdialog = prepareDialog();
    prdialog.show();
    //do some operations
    prdialog.dismiss();
}

An alternative solution (in case you want to call prepareDialog() multiple times, but reusing the dialog instead of creating a new one), would be:

void prepareDialog() {
    if (prDialog == null)
        prDialog = new ProgressDialog(this);

    prDialog.setTitle(R.string.Download);
    prDialog.setCanceledOnTouchOutside(false);
    prDialog.setCancelable(false);
    prDialog.setMessage(getString(R.string.Wait_));
}

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    prepareDialog();

    prdialog.show();
    //do some operations
    prdialog.dismiss();
}
Community
  • 1
  • 1
matiash
  • 54,791
  • 16
  • 125
  • 154
  • The solution isn't quite right. I think he was trying to get `prepareDialog` to create a new `ProgressDialog` only the first time, and your solution creates a new one every time. – ajb Jun 05 '14 at 22:31
  • @ajb Since it's called in `onCreate()`, I thought that wasn't necessary. But a fair point, I'll correct the example. – matiash Jun 05 '14 at 22:36
  • I always thought that java passes objects by reference, as in C++. – Vladislav Jun 05 '14 at 22:38
  • We don't know for sure that it isn't called somewhere else, also. In addition, looking at the Android activity lifecycle, it looks as though `onCreate()` could be called more than once on the same object. – ajb Jun 05 '14 at 22:40
  • @Vladislav Follow the link at the top of the answer. This will help explain things. – ajb Jun 05 '14 at 22:41
  • @ajb You're completely correct about the first point. But not about the second :) An Activity won't call onCreate() a second time, unless it's destroyed (and at that point it will be a different instance). – matiash Jun 05 '14 at 22:45
  • OK, then. I'm not yet an expert on Android, and the documentation of `onCreate()` isn't clear and I should know better than to trust that diagrams mean what they think they mean. Thanks. – ajb Jun 05 '14 at 23:04
0

Your call **prepareDialog(prdialog).show();** passes the reference of your **prdialog** object, but the method returns a fully constructed object that you ignore. As java is only pass by value (the value of reference is being passed here), you need to keep the reference of the returned object.

you have to do something like prdialog = prepareDialog(prdialog);. After that, your prdialog object will be fully constructed for your use.

V_Singh
  • 729
  • 11
  • 22