掌握android_掌握Android环境

掌握android

by Gaurav

通过高拉夫

掌握Android环境 (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.

Android中的上下文是最常使用和滥用的对象之一。 但是网络上的大多数文章都集中在对它的定义上。 我找不到能给我带来洞察力并帮助我理解大局的好资源。 因此,我尝试通过本文简化事情。

前言 (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.

本文的任务是帮助您掌握Android上下文。 这是Android开发的核心主题之一,几乎没有任何开发人员完全按照设计方式使用上下文。

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.

您是否遇到过以下问题: getContext()thisgetBaseContext()getApplicationContext()什么区别? 如果是,本文将帮助您澄清大部分困惑。

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.

注意:您应该了解Android开发的基础知识,例如Activity,Fragments,Broadcast Receiver和其他构件。 如果您是刚开始进入Android世界的新开发人员,那么这可能不是最佳开始。

上下文到底是什么? (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.

面对现实吧,上下文是Android API中设计最差的功能之一。 您可以将其称为“上帝”对象。

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).

Android应用程序或应用程序包工具包(APK)是一组组件。 这些组件在清单中定义,主要包括活动(UI),服务(背景),广播接收器(Action),ContentProvider(数据)和资源(图像,字符串等)。

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.

同样,Android操作系统也被设计为公开组件。 一些著名的是WifiManager,Vibrator和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.

我们使用上下文通过Activity,Content Provider,BroadcastReceiver等实例化组件。 我们也使用它来访问资源和文件系统。

您的组件和系统组件 (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).

上下文充当Android系统的入口点。 一些常用的系统组件是WifiManager,Vibrator和PackageManager。 您可以使用context.getSystemService(Context.WIFI_SERVICE)访问WifiManager。

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

以相同的方式,您可以使用上下文以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.

如果使用意图过滤器方法,则您自己的组件与其他应用程序组件之间的通信几乎是相同的。 毕竟,每个组件在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);

下面是用于发送电子邮件的意图示例。 提供此意图动作的所有组件都将提供给用户,用户可以选择使用什么。 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.

让我们同意,Android中的所有内容都是组件。 上下文是组件之间的桥梁。 您可以使用它在组件之间进行通信,实例化组件和访问组件。 我希望这个定义现在很清楚。

不同类型的上下文 (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:

在大多数情况下,当需要上下文时,我们使用以下之一:

- Application instance as context- Activity	- Instance of your activity (this)	- getApplicationContext() in Activity	- getBaseContext() in Activity- Fragment	- getContext() in Fragment- View	- getContext() in View- Broadcast Receiver	- Context received in broadcast receiver- Service	- Instance of your service (this)	- getApplicationContext() in Service- Context	- getApplicationContext() in Context instance

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 ContextNon-UI Context 。 这种区别将帮助您更好地理解n-ways

UI上下文 (UI Context)

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

实际上,只有ContextThemeWrapper是UI Context,即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.

活动扩展了ContextThemeWrapper 。 这就是为什么当您膨胀任何XML时,您的视图便会主题化的原因。 如果您使用Non-UI上下文来增加布局,则不会以主题为主题。 继续尝试。

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).

当您将“活动”用作上下文的占位符时,可以确保使用UI上下文。 如果您使用Fragment中的getContext方法,那么您将间接使用Activity(如果您通过Activity中的fragmentManager附加了Fragment)。

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

但是,不能保证view.getContext()是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.

如果使用Layout Inflater实例化了View并传递了UI Context,则将获得UI Context。 但是,如果通过不传递UI上下文来实例化它,则可以返回另一个上下文。

UI Context- Activity	- Instance of your activity (this)- Fragment	- getContext() in Fragment- View	- getContext() in View (if View was constructed using UI-Context)
非UI上下文 (Non-UI Context)

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

除UI上下文外,其他均为非UI上下文。 从技术上讲,任何不是ContextThemeWrapper的都是非UI上下文。

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

允许非UI上下文执行UI-Context 几乎可以做的所有事情( 发现不良设计 )。 但是,正如我们上面指出的那样,您会失去主题。

Non-UI Context- Application instance as context- Activity	- getApplicationContext() in Activity- Broadcast Receiver	- Context received in broadcast receiver- Service	- Instance of your service (this)	- getApplicationContext() in Service- Context	- getApplicationContext() in Context instance

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.

提示 :除了应用程序上下文外,所有上下文类型都应短暂存在。 这是您从应用程序类或具有上下文访问权限时使用getApplicationContext()方法获得的一种。

摘要 (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.

通过将上下文放入两个存储桶中,我们对其进行了一些简化。 UI Context是Context + Theming,从技术ContextThemeWrapper ,此bucket中都包含ContextThemeWrapper的子类。 非UI上下文是所有其他类型的上下文。

在哪里使用 (Where to use what)

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

随之而来的问题是:如果在错误的地方使用上下文会出现什么问题? 以下是一些方案:

场景1 (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.

假设您正在放大布局,并且使用了非UI上下文。 可能出什么问题了? 在这种情况下,您可以猜测:您不会获得主题布局。 还不错吧,嗯? 可以忍受的

方案2 (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.

您将UI-Context传递到只需要资源访问或文件系统访问的地方。 有什么不对的? 简短的回答:没什么。 记住,UI-Context =上下文+主题。 它将很高兴为您提供上下文。

场景3 (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.

您将UI-Context传递到某个地方,它所需要的只是资源访问或文件系统访问, 但这在后台需要很长时间。 说下载文件。 现在怎么了? 简短答案:内存泄漏。

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.

如果幸运的话,下载很快完成,则释放该对象,一切正常。 阳光普照,鸟鸣。 这是开发人员最常见的错误之一。 他们将对UI-Context的引用传递给寿命长的对象,有时副作用为零。

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.

但是,有时Android想要为您的下一个组件的要求或另一个组件的要求中的一个声明内存,并且woooshhhh !!! 您的应用程序内存不足。 不用担心,我会解释。

内存泄漏或崩溃! 而已。 (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.

是的,当您在错误的位置使用上下文时,这是最坏的情况。 如果您不熟悉应用程序开发领域,请让我分享一些智慧。 内存泄漏与您的体验成反比。 每个Android开发人员都泄漏了内存。 这样做是没有耻辱的。

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!!!

Android中的几乎所有内容都需要访问Context。 天真的开发人员通过UI Context,因为这是他们可以轻松访问的。 它们将短暂生存的上下文(通常是活动上下文)传递给寿命长的对象,并且在内存/金钱返回系统之前,他们遇到了危机。 哇!

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.

    您需要访问与UI相关的内容吗? 使用UI上下文。 我可以想到的是扩大视图和显示对话是两个用例。
  • Otherwise, Use Non UI Context.

    否则,请使用“非UI上下文”。
  • 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()?

是什么区别thisgetApplicationContext()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.

这是每个Android开发人员生活中遇到的一个问题。 我将尝试尽可能简化它。 让我们退后一步,回顾一下基础知识。

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?

尝试回答此问题:用户的配置当前处于纵向状态,并且您想访问横向资源。 或用户区域设置为en而您想访问uk资源。 你会怎么做?

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:

createX方法很多,但是我们主要对createConfigurationContext感兴趣。 使用方法如下:

Configuration configuration = getResources().getConfiguration();configuration.setLocale(your_custom_locale);context = createConfigurationContext(configuration);

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.

您可以拥有所需的任何类型的上下文。 在刚刚获得的新Context上调用任何方法时,您将可以根据已设置的配置访问资源。

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.

同样,您可以创建主题上下文,然后使用它来将所需主题的视图放大。

ContextThemeWrapper ctw = new ContextThemeWrapper(this, R.style.YOUR_THEME);

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

让我们回到上面提出的棘手问题,并讨论活动上下文。

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

是什么区别this getApplicationContext()getBaseContext()

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

当您处于“ Activity范围中时,可以使用以下几种方法来保留上下文。

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.

this 指向活动本身,我们的UI上下文和短寿命上下文。 getApplicationContext()指向您的应用程序实例,该实例是非UI且寿命很长的上下文。

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.

baseContext是您可以使用委托模式设置的活动上下文的基础。 您已经知道可以使用所需的任何xyz配置创建Context。 您可以将xyz配置知识与基本上下文结合起来,您的活动将根据需要加载资源。

Here is the method you can use:

这是您可以使用的方法:

@Overideprotected void attachBaseContext (Context base) {super.attachBaseContext(useYourCustomContext);}

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.

附加BaseContext ,您的Activity将把调用委派给该对象。 如果您未附加Activity,则它仍为baseContext并且在调用getBaseContext时会获得Activity。

结论 (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.

我们可以说上下文是您的Android应用程序的生命。 从Android的角度来看,它就是您的应用程序。 没有上下文,您几乎什么也做不了。 没有它,您的应用程序就是纯Java代码。

上下文+ Java代码=> Android (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.

在下一部分中,我们了解到Context可以是UI或NonUI,短期或长期。

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

之后,我们了解到您需要仔细选择上下文,否则必须处理内存泄漏和其他UI问题。

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.

最后,您看到Context负责为您的应用加载最佳匹配资源,并且您可以根据需要对其进行配置。 我们还了解到的区别thisapplicationContextbaseContext

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.

许多开发人员会建议您仅使用应用程序上下文。 不要因为担心内存泄漏而在各处使用Application Context。 了解根本原因,并始终在正确的位置使用正确的上下文。

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.

您,我亲爱的朋友,现在是Android Context的大师。 您可以建议您要了解的下一个主题。 点击这里建议

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

以下是原始系列精通Android上下文的链接 在我的博客上。

第1章 (Chapter 1)

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

上下文到底是什么? 我们为什么需要它?在日常开发中有哪些用例?

第2章 (Chapter 2)

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

简化上下文。 我们将讨论其中有几种类型的上下文,以及您打算使用哪种类型。

第3章 (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.

在哪里使用UI上下文以及在哪里使用非UI上下文。 如何在错误的位置使用上下文可能导致内存泄漏。

第四章 (Chapter 4)

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

我的UI上下文还为我提供了多种类型的上下文。 让我们回答这个问题,看看如何避免常见的陷阱。

训练 (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.

您是否知道您的应用多次崩溃是因为开发人员未正确使用Context? 让我们一起学习。 我提供有关Android,Java和Git的培训。

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

想掌握Android主题吗? 观看超过3k票的我们的系列。

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

随时分享您的反馈和问题。 编码愉快。

Follow me on Medium and Twitter for updates.

MediumTwitter上关注我以获取更新。

翻译自: https://www.freecodecamp.org/news/mastering-android-context-7055c8478a22/

掌握android

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值