Search code examples
androidandroid-activitysharedpreferencesandroid-viewandroid-context

Best approach to access an Activity on the inside of a (custom) view/dialog?


I have only one activity in my app. Before I just stored my views and dialogs static in the activity, so I could access them from anywhere. But I know that this is bad practice because it leads to memory leaks.

So I made them non-static, but now I need to have a reference to my activity deep down in my view hierarchy, to access the views and dialogs stored in the activity.

Example:

My MainActivity has a dialog called a and a custom view called b. How can the onClick method of b show the dialog a? enter image description here

or in code:

public class MainActivity extends Activity {
    private CustomDialog a;
    private CustomView b;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        a = new CustomDialog(this);
        b = new CustomView(this);
    }
}


public class CustomView extends Button implements OnClickListener {
    public CustomView(Context context) {
        super(context);
        setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        //wants to show dialog a
        MainActivity.a.show(); //Not possible -> a is not static
        mainActivity.a.show(); //<-- needs a reference of the activity
                               //    but where from?
    }
}

MainActivity mainActivity = (MainActivity) getContext(); won't work because getContext() is not always an activity context.

UPDATE:

I posted an answer below! For some reasons StackOverflow only lets me accept my own answer in two days


Solution

  • A few minutes a go there was an answer here that turned out to be correct. I don't know why the author deleted it, but it had a link to this answer:

    private static Activity unwrap(Context context) {
        while (!(context instanceof Activity) && context instanceof ContextWrapper) {
            context = ((ContextWrapper) context).getBaseContext();
        }
        return (Activity) context;
    }
    

    So everytime you need the activity you just can call Activity activity = unwrap(getContext());.

    I don't know if it is really intended to do it that way or if it is a workaround, but it does its job (atleast in my case).