Search code examples
androidandroid-activityconstructorfinal

Conflict between final field, constructor and onCreate in Android Activity


First, I've been looking for the answer all over, but didn't find anything that can explain how to resolve my case.

I want to declare a few final fields in my Android FragmentActivity and initialize them later (I need onCreate to be executed first to get the needed data) I know that I can initialize final fields only in the constructor, however, it is called before onCreate when nothing else is yet initialized, therefore the application crashes with java.lang.NullPointerException.

My code:

public class MyActivity extends FragmentActivity {
    private final File mPhotosDir;
    private final ConstraintLayout mConstraintLayout;
    ...
    // This is the constructor of MyActivity activity
    public MyActivity() {
        this.mPhotosDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        this.mConstraintLayout = findViewById(R.id.myActivityConstraintLayout);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
    }

Is it even possible to declare final fields in an activity and initialize them later? Shall I give up the final declaration?


Solution

  • Is it even possible to declare final fields in an activity and initialize them later?

    Not in Java, at least not directly. final fields need to be initialized directly (when the field is defined) or in a constructor. You cannot wait to define them until some later point in time.

    Kotlin supports this sort of thing via lateinit var properties.

    The closest thing that you can do in Java is to have the final field hold something that in turn holds the value that you need. For example, you can have a final field for an AtomicReference, and only set() the reference in onCreate(). However, going this approach just to have a final field is a code smell.