738

How can I get the context in a fragment?

I need to use my database whose constructor takes in the context, but getApplicationContext() and FragmentClass.this don't work so what can I do?

Database constructor

public Database(Context ctx)
{
    this.context = ctx;
    DBHelper = new DatabaseHelper(context);
}
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
tyczj
  • 71,600
  • 54
  • 194
  • 296

31 Answers31

1431

You can use getActivity(), which returns the activity associated with a fragment.
The activity is a context (since Activity extends Context).

AskNilesh
  • 67,701
  • 16
  • 123
  • 163
  • 230
    getActivity() can return null if it is called before onAttach of the respective fragment. – arne.jans Apr 29 '13 at 15:36
  • 1
    yes so check if it is null before using anything with context – tyczj Dec 02 '13 at 18:18
  • 4
    I was reading this Google blog on memory leaks...http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html . If I use the getActivity() method would the app not be at risk of memory leaks? The blog suggests "Try using the context-application instead of a context-activity" which isn't really possible as getApplicationContext() only works for the Activity class and not the Fragment class. – Simon Apr 06 '14 at 17:40
  • 49
    A solution for the problem of detached fragments is to store the value of `getActivity().getApplicationContext()` in an instance variable when the fragment is created and then use that context whenever you want inside the fragment class. That context will survive fragment detachments. – Piovezan Jun 11 '14 at 15:08
  • 10
    Instead of passing around the application context, create a static context inside your Application class and initialize it onCreate(): MyApplication.sContext = getApplicationContext(); then you can access it from any activity/fragment without worrying about detachment. – Eduard Feb 23 '15 at 18:18
  • One thing though. this method is added on API 23 and cannot be used if you are stuck with older APIs. In that case I would refer to the answer by imabox. Besides you kinda want to maintain the backwards compatibility if you work on a serious project. So there's that as well. – milaniez Jun 10 '16 at 18:24
  • 4
    @milaniez: `getActivity` has always been available. It's `getContext` which was added in API 23. – mhsmith Sep 15 '17 at 12:10
  • Why not use getContext() if its the context you are after? – Jeffrey Jul 28 '18 at 22:45
  • 2
    @EduardKotysh what a beautiful welcome party for memory leak :) – Farid May 03 '19 at 08:17
  • @Farid If `MyApplication` is holding a static reference to the *application* context, how could that result in a memory leak? I understand that, normally, the `onCreate()` method of `MyApplication` will only be called once: https://stackoverflow.com/a/7686586/1617737 . – ban-geoengineering May 03 '20 at 13:08
  • 1
    @Piovezan Does that create a chance for memory leakage? – Prof Mar 07 '21 at 01:43
  • 2
    @Prof I haven't been working with Android for years, but I don't think so. If you keep a reference for the application context only (which, as the name implies, lasts for the whole app lifecycle) you are not preventing anything from being garbage-collected sooner (longer? sorry about my English) than it is normally going to. Eduko's suggestion right below mine also seems fine based on the same principle. – Piovezan Mar 07 '21 at 01:55
138

To do as the answer above, you can override the onAttach method of fragment:

public static class DummySectionFragment extends Fragment{
...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        DBHelper = new DatabaseHelper(activity);
    }
}
Mateus Gondim
  • 5,362
  • 6
  • 31
  • 51
iambox
  • 1,381
  • 1
  • 8
  • 2
  • 3
    I would recommend this, as getActivity() returns null if onAttach isn't called yet. – arne.jans Apr 29 '13 at 15:36
  • 10
    But, keep in mind, when onAttach() is called, there are no views. So you cannot do anything with views yet! – Zordid Jun 03 '13 at 19:30
  • 2
    @iambox what if `DatabaseHelper` needed a `FragmentActivity` instead of an `Activity`? For example, for an `Adapter`... – Jago Jun 19 '13 at 11:27
  • 4
    If you store a reference to your activity in `onAttach(Activity activity)` then you should release it in `onDetach()` – vovahost Nov 14 '14 at 19:56
  • 3
    The `onAttach` method has been deprecated, `Overrides deprecated method in 'android.support.v4.app.Fragment'` – Muhammad Saqib May 05 '17 at 17:26
  • @MuhammadSaqib [Official docs give no indication it was deprecated](https://developer.android.com/reference/android/support/v4/app/Fragment#onAttach(android.content.Context)) – Izkata Jul 02 '18 at 04:25
  • This is now deprecated in androidx – Geoff Sep 28 '19 at 15:25
29

The easiest and most precise way to get the context of the fragment that I found is to get it directly from the ViewGroup when you call onCreateView method at least here you are sure not to get null for getActivity():

public class Animal extends Fragment { 
  Context thiscontext;
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
  {
    thiscontext = container.getContext();
sfmirtalebi
  • 370
  • 7
  • 16
Amer Elhabbash
  • 500
  • 4
  • 7
26

Always use the getActivity() method to get the context of your attached activity, but always remember one thing: Fragments are slightly unstable and getActivity returns null some times, so for that, always check the isAdded() method of fragment before getting context by getActivity().

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ankur Chaudhary
  • 2,709
  • 3
  • 19
  • 30
  • 17
    I would not say that fragments are "slightly unstable", it seems quite normal for getActivity() to return null when the fragment does not belong to an activity. It is assuming that getActivity() "should not return null" (which is wrong) that would make your app (and not the Fragment class) unstable. – personne3000 Apr 13 '14 at 02:31
  • 3
    @personne3000 I'd like to hear more. When is a fragment not belonging to an Activity? When is this happening and why? Should we be checking isAdded() in the fragment in order to use getActivity()? Any rule of thumb? – Sotti Apr 22 '15 at 15:41
  • 2
    @Sotti I encourage you to create a new question for this (or look for an existing one), since this specific subject is a little different from the original question. You can have a look at http://developer.android.com/guide/components/fragments.html#Lifecycle for general information. Basically, before onAttach and after onDetach, no activity. And between onAttach and onActivityCreated, the activity's onCreate has not been called yet. When using getActivity(), make sure your activity was already created, and think about what would happen if it was destroyed or your fragment was detached. – personne3000 Apr 22 '15 at 23:44
24

The correct way is to use

requireContext()

and the example

ContextCompat.getColor(requireContext(), R.color.colorAccent),
All Іѕ Vаиітy
  • 24,861
  • 16
  • 87
  • 111
19

Previously I'm using onAttach (Activity activity) to get context in Fragment

Problem

The onAttach (Activity activity) method was deprecated in API level 23.

Solution

Now to get context in Fragment we can use onAttach (Context context)

onAttach (Context context)

  • Called when a fragment is first attached to its context. onCreate(Bundle) will be called after this.

Documentation

/**
 * Called when a fragment is first attached to its context.
 * {@link #onCreate(Bundle)} will be called after this.
 */
@CallSuper
public void onAttach(Context context) {
    mCalled = true;
    final Activity hostActivity = mHost == null ? null : mHost.getActivity();
    if (hostActivity != null) {
        mCalled = false;
        onAttach(hostActivity);
    }
}

SAMPLE CODE

public class FirstFragment extends Fragment {


    private Context mContext;
    public FirstFragment() {
        // Required empty public constructor
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mContext=context;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rooView=inflater.inflate(R.layout.fragment_first, container, false);

        Toast.makeText(mContext, "THIS IS SAMPLE TOAST", Toast.LENGTH_SHORT).show();
        // Inflate the layout for this fragment
        return rooView;
    }

}

NOTE

We can also use getActivity() to get context in Fragments but getActivity() can return null if the your fragment is not currently attached to a parent activity,

AskNilesh
  • 67,701
  • 16
  • 123
  • 163
14

requireContext() method is the simplest option

requireContext()

Example

MyDatabase(requireContext())
12
@Override
public void onAttach(Activity activity) {
    // TODO Auto-generated method stub
    super.onAttach(activity);
    context=activity;
}
taran mahal
  • 1,068
  • 12
  • 11
7

You could also get the context from the inflater parameter, when overriding onCreateView.

public static class MyFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
        /* ... */
        Context context = inflater.getContext();
        /* ... */
    }
}
luizfls
  • 532
  • 6
  • 13
5

Another alternative approach is:

You can get the context using:

getActivity().getApplicationContext();
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
codercat
  • 22,873
  • 9
  • 61
  • 85
5

to get the context inside the Fragment will be possible using getActivity() :

public Database()
{
    this.context = getActivity();
    DBHelper = new DatabaseHelper(this.context);
}
  • Be careful, to get the Activity associated with the fragment using getActivity(), you can use it but is not recommended it will cause memory leaks.

I think a better aproach must be getting the Activity from the onAttach() method:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    context = activity;
}
Jorgesys
  • 124,308
  • 23
  • 334
  • 268
  • You shouldnt be using getActivity in a fragment to get a view unless that view is part of the activity anyway. Why would you inflate a view in a fragment then not even reference anything from it? – tyczj Dec 05 '14 at 22:53
  • This answer is about something different, you're talking about which view hiearchy to search for views in. `Activity.findViewById` is just a convenience method to search for a view in that activity's registered content view (set through `setContentView`). In your correct example you are calling `View.findViewById`, not `Activity.findViewById`, and you are invoking the method on the *correct* root view. Totally different problem, and obviously you won't be able to find your view in a view hiearchy that doesn't hold that view. – JHH Mar 02 '16 at 12:36
5

You can use the getActivity() method to get context or You can use getContext() method .

View root = inflater.inflate(R.layout.fragment_slideshow, container, false);
Context c = root.getContext();

I hope it helps!

Ramesh R
  • 7,009
  • 4
  • 25
  • 38
Rishabh Sharma
  • 169
  • 1
  • 3
  • 1
    There are other answers that provide the OP's question, and they were posted some time ago. When posting an answer [see: How do I write a good answer?](https://stackoverflow.com/help/how-to-answer), please make sure you add either a new solution, or a substantially better explanation, especially when answering older questions. – help-info.de Oct 24 '19 at 18:19
4

getContext() came in API 23. Replace it with getActivity() everywhere in the code.

See if it fixes the error. Try to use methods which are in between the target and minimun API level, else this error will come in place.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Naveen
  • 41
  • 1
3

Since API level 23 there is getContext() but if you want to support older versions you can use getActivity().getApplicationContext() while I still recommend using the support version of Fragment which is android.support.v4.app.Fragment.

Androbin
  • 991
  • 10
  • 27
3

For Kotlin you can use context directly in fragments. But in some cased you will find an error like

Type mismatch: inferred type is Context? but Context was expected

for that you can do this

val ctx = context ?: return
textViewABC.setTextColor(ContextCompat.getColor(ctx, android.R.color.black))
Kishan Solanki
  • 13,761
  • 4
  • 85
  • 82
  • Thanks for availing a Kotlin version, which works fine, however I am trying to get Context for Picasso.get(), with it and it never works, I have tried all i can from samples above as well to get context. At best I get this message -Too many arguments passed... Please help. val ctx = context ?: return Picasso.get(ctx) .load(selectedGallery.imageUrl) .placeholder(R.mipmap.ic_launcher) .into(galleryImage) – Ade Oct 29 '18 at 10:25
  • @Ade In your fragment, try to use "activity!!" instead of "ctx" and let me know it helps or not – Kishan Solanki Oct 29 '18 at 10:30
  • @ KishanSolanki124. Thanks very much for the quick response. I tried your suggestion, with the same result - Not working still. The exact error prompt is - Too many arguments for public open fun get(): Picasso!. This message makes me think, maybe something else is the error?. Gladly though, found a way to move on with my work by using Picasso without getting context. Thanks again. – Ade Oct 29 '18 at 12:32
3

In kotlin just use activity instead of getActivity()

Abduhafiz
  • 3,318
  • 5
  • 38
  • 48
2

getActivity() is a child of Context so that should work for you

qazimusab
  • 1,031
  • 1
  • 7
  • 14
2

You have different options:

  • If your minSDK <= 21, then you can use getActivity(), since this is a Context.
  • If your minSDK is >=23, then you can use getContext().

If you don't need to support old versions then go with getContext().

Rahul
  • 10,457
  • 4
  • 35
  • 55
Jorge
  • 1,353
  • 10
  • 25
2

Use fragments from Support Library -

android.support.v4.app.Fragment

and then override

void onAttach (Context context) {
  this.context = context;
}

This way you can be sure that context will always be a non-null value.

lomza
  • 9,412
  • 15
  • 70
  • 85
2

safe way to get context in fragment

if(isAdded){
requireActivit();//this is your context
}
Mostafa Onaizan
  • 923
  • 1
  • 5
  • 17
1

The simple way is to use getActivity(). But I think the major confusion of using the getActivity() method to get the context here is a null pointer exception.

For this, first check with the isAdded() method which will determine whether it's added or not, and then we can use the getActivity() to get the context of Activity.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    How is this different from [Ankur Chaudhary's answer](http://stackoverflow.com/questions/8215308/using-context-in-a-fragment/22174744#22174744)? – Peter Mortensen Jan 31 '16 at 17:25
1

Ideally, you should not need to use globals. The fragment has different notifications, one of them being onActivityCreated. You can get the instance of the activity in this lifecycle event of the fragment.

Then: you can dereference the fragment to get activity, context or applicationcontext as you desire:

this.getActivity() will give you the handle to the activity this.getContext() will give you a handle to the context this.getActivity().getApplicationContext() will give you the handle to the application context. You should preferably use the application context when passing it on to the db.

rink.attendant.6
  • 44,500
  • 61
  • 101
  • 156
1

You can call getActivity() or,

public void onAttach(Context context) {
    super.onAttach(context);
    this.activity = (CashActivity) context;
    this.money = this.activity.money;
}
Satan Pandeya
  • 3,747
  • 4
  • 27
  • 53
蔡健烽
  • 11
  • 2
1
public class MenuFragment extends Fragment implements View.OnClickListener {
    private Context mContext;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        FragmentMenuBinding binding=FragmentMenuBinding.inflate(inflater,container,false);
        View view=binding.getRoot();
        mContext=view.getContext();
        return view;
    }
}
Mohsinali
  • 543
  • 7
  • 14
1

In Kotlin you can use this: requireActivity().applicationContext

S. B.
  • 186
  • 1
  • 12
0

I think you can use

public static class MyFragment extends Fragment {
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

      Context context = getActivity.getContext();

  }
}
perror
  • 7,071
  • 16
  • 58
  • 85
0

I need context for using arrayAdapter IN fragment, when I was using getActivity error occurs but when i replace it with getContext it works for me

listView LV=getView().findViewById(R.id.listOFsensors);
LV.setAdapter(new ArrayAdapter<String>(getContext(),android.R.layout.simple_list_item_1 ,listSensorType));
Umair
  • 6,366
  • 15
  • 42
  • 50
Ghazaleh Javaheri
  • 1,829
  • 19
  • 25
0

On you fragment

((Name_of_your_Activity) getActivity()).helper

On Activity

DbHelper helper = new DbHelper(this);
Kinggeov
  • 184
  • 12
0

Inside fragment for kotlin sample would help someone

textViewStatus.setTextColor(ContextCompat.getColor(context!!, R.color.red))

if you use databinding;

bindingView.textViewStatus.setTextColor(ContextCompat.getColor(context!!, R.color.red))

Where bindingView is initialized in onCreateView like this

private lateinit var bindingView: FragmentBookingHistoryDetailBinding

bindingView = DataBindingUtil.inflate(inflater, R.layout.your_layout_xml, container, false)
Shihab Uddin
  • 6,699
  • 2
  • 59
  • 74
0

You can use getActivity(), which returns the activity associated with a fragment. The activity is a context (since Activity extends Context).

be careful: getActivity() can return null if it is called before onAttach of the respective fragment.

2.or

The easiest and most precise way to get the context of the fragment that I found is to get it directly from the ViewGroup when you call onCreateView method at least here you are sure not to get null for getActivity():

public class Animal extends Fragment { 
Context thiscontext;
@Override
public View onCreateView(LayoutInflater inflater, 
ViewGroup container, Bundle savedInstanceState)
{
thiscontext = container.getContext();
//...
//...
//...
}
-2

androidx.fragment.app.Fragment

@NonNull
public final android.content.Context requireContext()

Return the Context the fragment is currently associated with.

Since: getActivity and Context can be null, it is good practice to use requireContext() as it can't be null.

N-RAYAN
  • 123
  • 1
  • 1
  • 8
  • `it is good practice to use requireContext() as it can't be null.` that is nonsense, sure, it can't be null, because it will throw an exception if it is null when using require context. there's also [already an answer for this](https://stackoverflow.com/a/60486970/4729721) – a_local_nobody Mar 26 '22 at 19:53