0

I am new to programming. I have a simple app with only few activities, and I need to use Context in those activities. The link: https://openclassrooms.com/en/courses/4661936-develop-your-first-android-application/4679186-learn-the-model-view-controller-pattern and the answer in MVC for simple app say that I don´t need MVC for a simple app and I want to avoid using it. What would be best practice for getting the contexts in my case? I think static Context can cause memory leaks. Should I just call getContext() every time I need context? (I tested it, it works). It doesn´t work with this, only with getContext(). I think it´s because it is inside of fragments. Thank you

For better understanding: this is a part of what I have:

public class MainApplication extends Application 
{
    @Override
    public void onCreate()
    {
        super.onCreate();
        FirstManager.createInstance(getApplicationContext());
    }
}

I pass this context with the help of a constructor to FirstManager. If I have more activities/classes than only FirstManager, is it better practice to write again getApplicationContext() or to write in class scope something like: Context context; after onCreate:getContext() and save it into context?

UPDATE: This is the fragment (other fragments are similar, nothing special):

public class List extends Fragment {
...
private FloatingActionButton fab;
    private FloatingActionButton fdb;
    private RecyclerView recyclerView;
...

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        fab = ( FloatingActionButton ) view.findViewById(R.id.floatingActionButton);
        recyclerView = (RecyclerView) view.findViewById(R.id.RView);
        fdb = ( FloatingActionButton ) view.findViewById(R.id.floatingDeleteButton);


            fab.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    startActivity(new Intent(getContext(), FloatingButtonActivity.class));
                }
            });
            recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(getContext(),1);
            recyclerView.addItemDecoration(dividerItemDecoration);
        }
 @Override
        public void onResume() {
            super.onResume();
            final RAdapter radapter = new RAdapter(getContext(),getActivity());
            recyclerView.setAdapter(radapter);

            fdb.hide();
            fdb.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    radapter.deleteSelection();
                }
            });
        }
}
Tony
  • 11
  • 4
  • Never use static contexts. Never. Now what you ask depends on what you need to do. Activities, Views and Fragments all have context, so give a few more details. – iFanie Nov 29 '18 at 20:32
  • Sounds like good practice, but explain to me specifically what you need to do with the context. – iFanie Nov 30 '18 at 19:16

1 Answers1

1

In every Fragment you can use getContext or getActivity and use them however you like. Keep in mind both are Nullable, and will be null if the root view of the Fragment has not been created. Some sample code:

@Override
public void onViewCreated(View view) {
    ...

    Context context = getContext();
    if (context != null) {
        startActivity(new Intent(context, FloatingButtonActivity.class));
        ...
        recyclerView.setLayoutManager(new LinearLayoutManager(context));
        ...
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context);
    }
}

There is no performance difference between using this local variable and getContext every time, you just get rid of warnings about the context being null.

And since the context is not exposed outside an entity that will have a lifecycle past the Fragment or Activity (meaning that you don't give the context to any class instance that might live on after the Fragment or Activity is killed), from this code you won't have leaks.

iFanie
  • 916
  • 8
  • 10
  • I hope I understand you correctly: If I need a fragment´s context twice or more times, it´s good practice to create the fragment´s context (name: mContext) in class scope. After that I can call `getContext` when I need it the first time in this fragment. After that I just use "mContext" everytime I need context in this fragment. In this case it´s better performance because the device doesn´t have to do `getContext` more than once per fragment? – Tony Dec 01 '18 at 17:56
  • And how can it happen that the root view of the Fragment has not been created? – Tony Dec 01 '18 at 18:04
  • 1
    @Tony call getContext as much as you need, i would not even assign it to a variable like ```mContext```. If you were writing Kotling code it would work as a property and you would not even think about it. Root view might not exist if you create the fragment and don't attach it to an Activity. – iFanie Dec 01 '18 at 18:21
  • thanks, last question I hope: What do I do in your described case? – Tony Dec 01 '18 at 20:06
  • @Tony the Fragment docs instruct you do anything related to views in the ```onViewCreated``` override. There you are sure you have a root view (and a context). I would start by moving any such login from ```onCreateView``` to ```onViewCreated```, if that applies to you. If something specific bothers you, share code and i'd be happy to help. – iFanie Dec 02 '18 at 20:17
  • thank you. This is a part of my code and it´s in onViewCreated: [...]`startActivity(new Intent(getContext(), FloatingButtonActivity.class));` [...]`recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));` [...]`DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(getContext()<--,1);`<-- it says: this one might be null...why? It doesn´t say that for the first and second getContext(). But you say this is a good way to getContext() and it doesn´t drain much battery/performance/memory leak? – Tony Dec 02 '18 at 22:37
  • @Tony ok, i see. That is just the code analysis of Android Studio being wonky, I guess. I'll update my answer with those lines of code and how i would handle it with a local variable inside the onViewCreated. – iFanie Dec 03 '18 at 05:12
  • If I only write `Context mContext` in the class scope without any `getContext()` and use `mContext`whenever I need context in this fragment, it works, too. Is it worse practice? I don´t understand why you check for `context!=null`: In my case it would be very bad if the code just stops there, I feel like it´s more likely that a problem can occur when I build the code like this. – Tony Dec 06 '18 at 22:35
  • @Tony it doesn't sound like worse practice. If you want, post the whole thing to have a look. – iFanie Dec 07 '18 at 07:09
  • I updated the post. It´s how I had it from the start. – Tony Dec 07 '18 at 21:41
  • @Tony either what i wrote, or what you did originally, inside a fragment it's absolutely fine. – iFanie Dec 10 '18 at 08:16