Define context in android

Context

Context – это объект, который предоставляет доступ к базовым функциям приложения: доступ к ресурсам, к файловой системе, вызов активности и т.д. Activity является подклассом Context, поэтому в коде мы можем использовать её как ИмяАктивности.this (напр. MainActivity.this), или укороченную запись this. Классы Service, Application и др. также работают с контекстом.

Доступ к контексту можно получить разными способами. Существуют такие методы как getApplicationContext(), getContext(), getBaseContext() или this, который упоминался выше, если используется в активности.

На первых порах не обязательно понимать, зачем он нужен. Достаточно помнить о методах, которые позволяют получить контекст и использовать их в случае необходимости, когда какой-нибудь метод или конструктор будет требовать объект Context в своих параметрах.

В свою очередь Context имеет свои методы, позволяющие получать доступ к ресурсам и другим объектам.

  • getAssets()
  • getResources()
  • getPackageManager()
  • getString()
  • getSharedPrefsFile()

Возьмём к примеру метод getAssets(). Ваше приложение может иметь ресурсы в папке assets вашего проекта. Чтобы получить доступ к данным ресурсам, приложение использует механизм контекста, который и отвечает доступность ресурсов для тех, кто запрашивает доступ — активность, служба и т.д. Аналогично происходит с методом getResources. Например, чтобы получить доступ к ресурсу цвета используется конструкция getResources().getColor(), которая может получить доступ к данным из файла res/colors.xml.

Таким образом, создавая, например, вторую активность, мы можем сразу обеспечить ей доступ к своим ресурсам, так как активность относится к контексту. При создании собственных компонентов View также используется контекст в конструкторах, так как компонент тоже может использовать ваши ресурсы. При создании собственных классов, если вам нужно будет обращаться к контексту, то необходимо создать конструктор:

Через контекст можно узнать практически всю информацию о вашем приложении — имя пакета, класса и т.п.

Тем не менее, следует различать контекст в разных ситуациях. Допустим, у вас есть приложение с несколькими активностями. В манифесте можно прописать используемую тему как для всего приложения, так и для каждой активности в отдельности. Соответственно, выбор контекста повлияет на результат. Как правило, при использовании собственной темы предпочтительнее использовать контекст активности, а не приложения.

Очень часто начинающие программисты впадают в ступор, когда ключевое слово this не работает в анонимных классах, например, при щелчке кнопки. В этом случае, используйте полное имя класса перед ним.

При создании адаптеров для списков также обращаются к контексту.

Или ещё пример для адаптера в фрагменте ListFragment:

Здесь тоже следует быть внимательным, если используется своя тема для списка.

Последнее замечание относится к опытным программистам. Неправильный контекст может послужить источником утечки памяти. Если вы создадите собственный класс, в котором содержится статическая переменная, обращающая к контексту активности, то система будет держать ссылку на переменную. Если активность будет закрыта, то сборщик мусора не сможет очистить память от переменной и самой неиспользуемой активности. В таких случаях лучше использовать контекст приложения через метод getApplicationContext().

ContextCompat

В библиотеки совместимости появился свой класс для контекста ContextCompat. Он может вам пригодиться, когда студия вдруг подчеркнёт метод в старом проекте и объявит его устаревшим.

Допустим, мы хотим поменять цвет текста на кнопки.

Студия ругается, что нужно использовать новый вариант getColor(int, Theme). Заменим строчку.

Если посмотреть на исходники этого варианта, то увидим, что там тоже идёт вызов нового метода. Поэтому можно сразу использовать правильный вариант, если вы пишете под Marshmallow и выше.

Источник

What is Context in Android and which one should you use?

Jan 19, 2020 · 5 min read

I find Context in Android, as one of the most difficult things to explain to anyone. When I started with Android development 2 years ago, I couldn’t wrap my head around the Context for a long period of time. I was so confused about it and yet I was using it on regular basis, simple because it is one of the fundamental things in Android. Still every time I needed to perform some operation that requires the Context, I felt anxious and I didn’t know how to “get” the right one.

Motivated by my confusion in early stages of my career as Android developer, I decided to express my understanding of Context and hope it will help someone who has just entered the world of Android and has no idea what does Context represent. Of course this article is also for anyone who wants to try to understand Context better. Now let’s get started.

In the official Android documentation here is how they defined Context.

Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.

At the beginning, this didn’t mean much to me. But as time passed, I started understanding its meaning.

Firstly, let’s look at 3 most used function for retrieving the Context:

  • getContext() — returns the Context which is linked to the Activity from which is called,
  • getApplicationContext() — returns the Context which is linked to Application which holds all activities running inside it,
  • getBaseContext() —is related to ContextWrapper, which is created around existing Context and let us change its behavior. With getBaseContext() we can fetch the existing Context inside ContextWrapper class.

To understand core of the Context, we will focus on first two methods mentioned above, because getBaseContext() is based on understanding regular Context and ContextWrapper.

Читайте также:  Apple pencil аналоги для андроид

getContext()

In getContext(), Context is tied to an Activity and its lifecycle. We can imagine Context as layer which stands behind Activity and it will live as long as Activity lives. The moment the Activity dies, Context will too.

Activity’s Context has its own functionalities, which we can use for all sort of things Android framework supports. Here is the list of functionalities Activity’s Context provides us:

getApplicationContext()

In getApplicationContext(), our Context is tied to Application and its lifecycle. We can think of it as layer behind whole application. As long as user doesn’t kill the application, it’s alive.

You may wonder now, what is the difference between getContext() and getApplicationContext(). The difference is that Application’s Context is not UI related. It means that, we shouldn’t use it to Inflate a Layout, Start an Activity nor Show a Dialog. Regarding the rest of the functionalities from Activity’s Context, they are available from Application’s Context also. So the list of functionalities for Application’s Context looks like this:

Now that we checked the functionalities which different types of Context provide us, we can try to roughly describe its meaning. We can say the following

Context is a layer(interface) which stands behind its component (Activity, Application…) and component’s lifecycle, which provides access to various functionalities which are supported by application environment and Android framework.

The most used functionalities provided by Context are loading resources (such as strings, assets, themes…), starting Activities and Services and inflating layouts.

I hope by now you learnt something new and you understand Context a little bit better than you did before reading this article. Still, there is one more important thing which you need to consider when choosing the right Context.

One thing to pay attention when deciding which Context to choose

In this article, a lot of times was mentioned Context which is tied to component’s lifecycle. I would like to emphasize that this is important to consider because if you choose the wrong one, it can lead to memory leak, which can lead to breaking your app, which can lead to very very disappointing results.

The easiest way of showing you what do I mean by choosing the right Context, is by showing you an example.

Example

We have singleton (class which can have only 1 instance during the whole application lifecycle) ContextSingleton, which holds reference to a Context.

As you can see, our singleton hold the Context reference, but the thing is that our mContext could be any type of context, it could be Application’s or Activity’s. (there are more types of Context but in this article I chose to write only about Application and Activity one)

Why should I care?

Well, imagine you pass the Activity’s Context here. Our singleton, will contain reference to the Activity whose Context was passed. Aside from that, we know that our singleton will outlive the Activity. That will lead to Activity which won’t be garbage collected when killed, because it is referenced by ContextSingleton. This principal is going to lead to memory leak.

To solve this issue, we need to realize that our singleton has lifecycle similar to application’s one. Than it is trivial to conclude that by passing the Application’s Context in singleton, we will overcome this type of problem. To solve it, we just need to hold the reference of getApplicationContext() called from any context.

Conclusion

In this article I tried to express my way of understanding the Context in Android. We’ve also covered functionalities which provide Activity and Application Context, their difference and how you can decide which one you should use in different situations.

The goal of this article was to try to help new Android developers roughly understand what is Context in Android and why do we use it. There is still a lot more to learn regarding Context and its capabilities. For anyone who is trying to investigate more regarding Context, I can recommend this great article by Dave Smith.

I really hope that I brought you closer to understanding the Context in Android. If there were parts of article which you found hard to process, feel free to comment them. I’ll do my best to update the article depending on feedback.

Thank you for taking time to read my article.

Also I am always open for commenting on Android stuff, so if you feel like talking, contact me on twitter or linkedin.

Источник

Mastering Android context

Context in Android is one of the most used and abused objects. But most of the articles on the web focus on the definition of what it is. I could not find a good resource which gave me insight and helped me understand the bigger picture. So I tried simplifying things with this article.

Preface

My mission for this article is to help you master Android Context. This is one of the core topics of Android development, and hardly any developers use context completely and in the way it was designed.

I originally published this article as a series of four posts on my website. If you are interested in reading chapter by chapter, feel free to read there.

Getting started

Have you ever encountered this question: What is difference between getContext() , this , getBaseContext() , and getApplicationContext() ? If yes, this article will help clarify most of your confusion.

Note: you should know the basics of Android development, like Activity, Fragments, Broadcast Receiver, and other building blocks. If you are a new developer who is just starting your journey into the Android world, this might not be the best place to begin.

Читайте также:  Запрет рекламы для андроид

What the heck is context?

Let’s face it, Context is one of the most poorly designed features of the Android API. You could call it the “God” object.

An Android app or application package kit (APK) is a bundle of components. These components are defined in the Manifest, and consist mainly of Activity (UI), Service (Background), BroadcastReceiver (Action), ContentProvider (Data), and Resources (images, strings etc).

The developer can choose to expose those components to a system using an intent-filter. For example: send email or share picture. They can also choose to expose the components only to other components of their app.

Similarly, the Android operating system was also designed to expose components. A few well known are WifiManager, Vibrator, and PackageManager.

Context is the bridge between components. You use it to communicate between components, instantiate components, and access components.

Your own components

We use context to instantiate our components with Activity, Content Provider, BroadcastReceiver, and so on. We use it to access resources and filesystems as well.

Your component and a system component

Context acts as an entry point to the Android system. Some well-used System components are WifiManager, Vibrator, and PackageManager. You can access WifiManager using context.getSystemService(Context.WIFI_SERVICE) .

In this same way, you can use context to access the filesystem dedicated to your app as a user in OS.

Your own component and some other app’s component

Communicating between your own components and other app’s components is almost identical if you use the intent-filter approach. After-all, every components is an equal citizen in Android.

An example of an intent used to send email is below. All components which are offering this intent action will be served to the user who can opt what to use.
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);

Summary

Let’s agree that everything in Android is a component. Context is the bridge between components. You use it to communicate between components, instantiate components, and access components. I hope the definition is now clear.

Different types of Context

There are many ways you can get a hold on context ( bad design spotted).

Most of the time we use one of the following when we need context:

I divide context types into two categories: UI Context and Non-UI Context. This distinction will help you understand n-ways a little better.

UI Context

In reality, only the ContextThemeWrapper is UI Context — which means Context + Your theme.

Activity extends ContextThemeWrapper . This is the reason that, when you inflate any XML, your views are themed. If you inflate your layout with Non-UI context, your layout will not be themed. Go ahead, try it.

When you use Activity as a placeholder for Context, you are guaranteed to be using UI Context. If you use the getContext method from Fragment, you are indirectly using Activity (if you attached Fragment via fragmentManager in activity).

But view.getContext() is not guaranteed to be UI Context.

If View was instantiated using Layout Inflater and passed UI Context, you get UI Context back. But if it was instantiated by not passing UI Context, you get the other context back.

Non-UI Context

Anything except UI Context is Non-UI Context. Technically, anything which is not ContextThemeWrapper is Non-UI Context.

Non-UI Context is allowed do almost everything UI-Context can do ( bad design spotted). But as we pointed out above, you lose theming.

Tip: All context types are supposed to be short lived except Application context. This is the one you get from your application class or from using the getApplicationContext() method when you have context access.

Summary

We have simplified it a little bit by putting Context in two buckets. UI Context is Context + Theming, and technically any class which is a subclass of ContextThemeWrapper comes in this bucket. Non-UI Context is all other types of Context.

Where to use what

The question arises: what will go wrong if you use context in the wrong place? Following are a few scenarios:

Scenario 1

Lets say you are inflating a layout and you use Non-UI Context. What may go wrong? You can guess in this case: you will not get a themed layout. Not so bad, hmm? It’s bearable.

Scenario 2

You pass UI-Context to someplace where all it needs is resource access or file system access. What can no wrong? Short Answer: Nothing. Remember, UI-Context = Context + Theme. It will gladly serve as context for you.

Scenario 3

You pass UI-Context to someplace where all it needs is resource access or file system access but it is a long operation in the background. Say downloading a file. Now what can go wrong? Short Answer: Memory leak.

If you are lucky and download completes quickly, the object is released and everything is fine. Sun is shining and birds are chirping. This is one of the most common mistakes developers make. They pass the reference of UI-Context to long living objects, and sometimes it has zero side effect.

However, sometimes Android wants to claim memory for either one of your next component’s requirements or another component’s requirements, and woooshhhh. You run out of memory in your app. Don’t worry, I will explain.

Memory Leak or Crash! That’s it.

Yes this is the worst case scenario when you use context in the wrong place. If you are new to the app development world, let me share some wisdom. Memory leaks are inversely proportional to your experience. Every Android developer has leaked memory. There is no shame in doing so.

Shame is when you repeat the mistake again and leak it the same way. If you leak memory a different way every time, congrats you are growing. I have explained what a Memory leak is with a short story here.

Читайте также:  Как убрать рекламный вирус с андроида

Okay I get it, but what is the relation of Context here?

Say it aloud, “Bad Design Spotted».

Almost everything in Android needs access to Context. Naive developers pass UI Context, because that’s what they have access to very easily. They pass short-living context (usually Activity context) to long living objects and before the memory/money is returned back to system, they hit a crisis. Woooshhh.

The simplest way to deal with this is with Async Task or Broadcast Receiver. But discussing them isn’t in the scope of this article.

Summary

  • Do you need to access UI related stuff? Use UI-Context. Inflating Views and showing dialogue are the two use cases I can think of.
  • Otherwise, Use Non UI Context.
  • Make sure you do not pass short-living context to long-living objects.
  • Pass knowledge, help people, plant trees and invite me for a coffee.

Tips and Tricks

What is the difference between this , getApplicationContext() and getBaseContext() ?

This is one question every Android developer have encountered in their lives. I will try to simplify it as much as possible. Let’s take a step back and revisit the basics.

We know there are many factors in mobile devices. For instance, configuration changes all the time, and locale can change explicitly or implicitly.

All of these changes trigger apps to re-create so they can pick the right resources that are the best match to their current configuration. Portrait, Landscape, Tablet, Chinese, German, and so on. Your app needs the best possible resources to deliver the best user experience. It is the Context which is responsible for delivering those best match resources.

Try answering this question:
The user’s configuration is currently in portrait and you want to access landscape resources. Or the user locale is en and you want to access uk resources. How will you do it?

Below are some magical methods from Context:

There are many createX methods, but we are mainly interested in createConfigurationContext . Here is how you can use it:

You can get a hold of any type of Context you desire. When you call any method on the new Context you just got, you will get access to resources based on the configuration you had set.

I know it is amazing. You can send me thank you card.

Similarly, you can create a Themed Context and use it to inflate views with the theme you want.

Let’s come back to the tricky question we asked above and discuss Activity Context.

What is the difference between this , getApplicationContext() and getBaseContext() ?

These are the possible ways you can get a hold on Context when you are in the Activity scope.

this points to Activity itself, our UI Context and short life context. getApplicationContext() points to your application instance which is Non-UI and long living context.

baseContext is the base of your Activity Context which you can set using a delegate pattern. You already know you can create Context with any xyz configuration you want. You can combine your xyz configuration knowledge with Base Context and your Activity will load resources as you desire.

Here is the method you can use:

Once BaseContext is attached, your Activity will delegate calls to this object. If you do not attach to Activity, it remains baseContext and you get Activity when you call getBaseContext .

Conclusion

We can say Context is the life of your android app. From Android’s point of view, it is your app. You can do almost nothing without Context. Without it, your app is plain Java code.

Context + Java code => Android

Good or bad, it is the design we have and we have to make the best of it. From the first part of this article, we learned that we use it to communicate between components, instantiate components, and access components.

In the next part, we learned that Context can be UI or NonUI, Short Lived or Long lived.

Following that, we learned that you need to choose context carefully otherwise you have to deal with memory leaks and other UI issues.

Finally, you saw that Context is responsible for loading best match resources for your app and you can configure it as you want. We also learned the difference between this , applicationContext and baseContext .

Many developers will advise you to use only application context. Do not use Application Context everywhere from the fear of a memory leak. Understand the root cause and always use the right Context in the right place.

You, my dear friend, are a master of Android Context now. You can suggest the next topic you want to understand. Click here to suggest.

Below are links from the original Series Mastering Android Context on my blog.

Chapter 1

What the heck is Context? Why do we need it and what are various use cases in day to day development?

Chapter 2

Simplifying Context. We will discuss how many types of context are there and which ones are you suppose to use.

Chapter 3

Where to use UI Context and where to use Non UI-Context. How using context at wrong place may lead to memory leaks.

Chapter 4

My UI Context also offers me multiple types of context. Let’s answer this question and see how to avoid common pitfalls.

Training

Do you know that many times your app is crashing because your developers are not using Context properly? Let’s learn together. I offer training in Android, Java, and Git.

Want to master Android themes? Check out our series with more than 3k upvotes.

Feel free to share your feedback and questions. Happy Coding.

Follow me on Medium and Twitter for updates.

Источник

Оцените статью