Daniel Lavín
Daniel Lavín

Reputation: 19

onAttach(Context context) not being called

I am trying to create an DialogFragment for an android application using API 23. I found that the onAttach method has been updated for this API, needing now a Context as an argument. The problem is, I just cannot get my DialogFragment to get attached to my Activity. I'm getting the following exceptions:

02-10 21:09:31.852 22647-22647/com.dactylotech.dactylo E/AndroidRuntime: FATAL EXCEPTION: main
 Process: com.dactylotech.dactylo, PID: 22647
 java.lang.IllegalStateException: Fragment ConnectionTypeAlertDialogFragment{c9d04dd} not attached to Activity
     at android.app.Fragment.getResources(Fragment.java:805)
     at android.app.Fragment.getString(Fragment.java:827)
     at com.dactylotech.dactylo.ConnectionTypeAlertDialogFragment.<init>(ConnectionTypeAlertDialogFragment.java:17)
     at com.dactylotech.dactylo.ListBTDevicesActivity$PairedBTDevicesClickable.onItemClick(ListBTDevicesActivity.java:129)
     at android.widget.AdapterView.performItemClick(AdapterView.java:310)
     at android.widget.AbsListView.performItemClick(AbsListView.java:1145)
     at android.widget.AbsListView$PerformClick.run(AbsListView.java:3049)
     at android.widget.AbsListView$3.run(AbsListView.java:3886)
     at android.os.Handler.handleCallback(Handler.java:746)
     at android.os.Handler.dispatchMessage(Handler.java:95)
     at android.os.Looper.loop(Looper.java:148)
     at android.app.ActivityThread.main(ActivityThread.java:5443)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

After doing a thorough research and having found no real answer, and instead discovering many people having the exact same problem and claiming it was bugged, I decided to look into the code for onAttach, which is the following:

public void onAttach(Context context) {
    mCalled = true;
    final Activity hostActivity = mHost == null ? null : mHost.getActivity();
    if (hostActivity != null) {
        mCalled = false;
        onAttach(hostActivity);
    }
}

If I'm not mistaken, hostActivity can either be assigned null or mHost.getActivity(). However, as this is the first call to mHost (following android's Fragment lifecycle), mHost is null from the beginning. This means that the expression evaluates to TRUE and so, it gets assigned null again!! Again, if I'm not mistaken, this is why onAttach(hostActivity) is never called, and therefore the DialogFragment is never attached to the Activity.

My question is, am I correct? Is this why this is happening? I want to get another point of view at this. Is there any way to get around this?

EDIT: The code displayed here for onAttach is the code from the Fragment java class. (android.app.Fragment)

EDIT #2: Whelp, it seems there is no error at all. Solution to my problem has been posted.

Upvotes: 1

Views: 954

Answers (1)

tynn
tynn

Reputation: 39853

In your fragment's constructor you're calling to Fragment.getString(). This method requires a context to fetch the resources to fetch the string and thus tries to get the activity.

Fragment ConnectionTypeAlertDialogFragment{c9d04dd} not attached to Activity tells you that the activity is not set. This is because the constructor is called before any other life-cycle event like onAttach().

You should refrain from doing any initialization of the fragment in the constructor and only use the life-cycle events. Like this you can ensure the state you need. Instead you could move the logic around getString() to onAttach() for example.

Upvotes: 3

Related Questions