context詳解

1、Context概念:

Context,相信不管是第一天開發Android,還是開發Android的各種老鳥,對于Context的使用一定不陌生~~你在加載資源、啟動一個新的Activity、獲取系統服務、獲取內部文件(夾)路徑、創建View操作時等都需要Context的參與,可見Context的常見性。大家可能會問到底什么是Context,Context字面意思上下文,或者叫做場景,也就是用戶與操作系統操作的一個過程,比如你打電話,場景包括電話程序對應的界面,以及隱藏在背后的數據; 
Android系統的角度來理解:Context是一個場景,代表與操作系統的交互的一種過程。從程序的角度上來理解:Context是個抽象類,而Activity、Service、Application等都是該類的一個實現。 

可以看到Activity、Service、Application都是Context的子類;
在仔細看一下上圖:Activity、Service、Application都是繼承自ContextWrapper,而ContextWrapper內部會包含一個base context,由這個base context去實現了絕大多數的方法。

2、Context與ApplicationContext:

看了標題,千萬不要被誤解,ApplicationContext并沒有這個類,其實更應該叫做:Activity與Application在作為Context時的區別。嗯,的確是這樣的,大家在需要Context的時候,如果是在Activity中,大多直接傳個this,當在匿名內部類的時候,因為this不能用,需要寫XXXActivity.this,很多哥們會偷懶,直接就來個getApplicationContext。那么大家有沒有想過,XXXActivity.this和getApplicationContext的區別呢?XXXActivity和getApplicationContext返回的肯定不是一個對象,一個是當前Activity的實例,一個是項目的Application的實例。既然區別這么明顯,那么各自的使用場景肯定不同,亂使用可能會帶來一些問題。下面開始介紹在使用Context時,需要注意的問題。

3、引用的保持

大家在編寫一些類時,例如工具類,可能會編寫成單例的方式,這些工具類大多需要去訪問資源,也就說需要Context的參與。在這樣的情況下,就需要注意Context的引用問題。例如以下的寫法:
 1 package com.mooc.shader.roundimageview;
 2 
 3 import android.content.Context;
 4 
 5 public class CustomManager
 6 {
 7     private static CustomManager sInstance;
 8     private Context mContext;
 9 
10     private CustomManager(Context context)
11     {
12         this.mContext = context;
13     }
14 
15     public static synchronized CustomManager getInstance(Context context)
16     {
17         if (sInstance == null)
18         {
19             sInstance = new CustomManager(context);
20         }
21         return sInstance;
22     }
23     
24     //some methods 
25     private void someOtherMethodNeedContext()
26     {
27         
28     }
29 }
View Code
對于上述的單例,大家應該都不陌生(請別計較getInstance的效率問題),內部保持了一個Context的引用;
這么寫是沒有問題的,問題在于,這個Context哪來的我們不能確定,很大的可能性,你在某個Activity里面為了方便,直接傳了個this;這樣問題就來了,我們的這個類中的sInstance是一個static且強引用的,在其內部引用了一個Activity作為Context,也就是說,我們的這個Activity只要我們的項目活著,就沒有辦法進行內存回收。而我們的Activity的生命周期肯定沒這么長,所以造成了內存泄漏。那么,我們如何才能避免這樣的問題呢?有人會說,我們可以軟引用,嗯,軟引用,假如被回收了,你不怕NullPointException么。把上述代碼做下修改:
1 public static synchronized CustomManager getInstance(Context context)
2     {
3         if (sInstance == null)
4         {
5             sInstance = new CustomManager(context.getApplicationContext());
6         }
7         return sInstance;
8     }
View Code
這樣,我們就解決了內存泄漏的問題,因為我們引用的是一個ApplicationContext,它的生命周期和我們的單例對象一致。
這樣的話,可能有人會說,早說嘛,那我們以后都這么用不就行了,很遺憾的說,不行。上面我們已經說過,Context和Application Context的區別是很大的,也就是說,他們的應用場景(你也可以認為是能力)是不同的,并非所有Activity為Context的場景,Application Context都能搞定。下面就開始介紹各種Context的應用場景。

?

4、Context的應用場景

?

?

大家注意看到有一些NO上添加了一些數字,其實這些從能力上來說是YES,但是為什么說是NO呢?下面一個一個解釋:數字1:啟動Activity在這些類中是可以的,但是需要創建一個新的task。一般情況不推薦。數字2:在這些類中去layout inflate是合法的,但是會使用系統默認的主題樣式,如果你自定義了某些樣式可能不會被使用。數字3:在receiver為null時允許,在4.2或以上的版本中,用于獲取黏性廣播的當前值。(可以無視)注:ContentProvider、BroadcastReceiver之所以在上述表格中,是因為在其內部方法中都有一個context用于使用。好了,這里我們看下表格,重點看Activity和Application,可以看到,和UI相關的方法基本都不建議或者不可使用Application,并且,前三個操作基本不可能在Application中出現。實際上,只要把握住一點,凡是跟UI相關的,都應該使用Activity做為Context來處理;其他的一些操作,Service,Activity,Application等實例都可以,當然了,注意Context引用的持有,防止內存泄漏。

5、總結

好了,到此,Context的分析基本完成了,希望大家在以后的使用過程中,能夠稍微考慮下,這里使用Activity合適嗎?會不會造成內存泄漏?這里傳入Application work嗎?由于參考內容過多,本文改為譯文咯~~

?

轉載于:https://www.cnblogs.com/UniqueColor/p/4735460.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/397677.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/397677.shtml
英文地址,請注明出處:http://en.pswp.cn/news/397677.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Unity Camera的兩種模式

http://www.cnblogs.com/zhaoqingqing/p/3302484.html

mysql之group_concat函數

mysql之group_concat函數 在介紹GROUP_CONCAT之前,我們先來看看concat()函數和concat_ws()函數。 先準備一個測試數據庫: mysql> select * from scores; --------------------- | id | name | score | --------------------- | 1 | zhangsan | 1…

java 圖片批量上傳_java實現批量上傳圖片,還要保證每個圖片的順序號,疑問求教!...

rt我要一次性同時上傳n張照片,并且每張照片的順序號還不一樣,第一張的serialno是1,第二張是2。。一開始我做單張圖片上傳,代碼如下RequestMapping("/picUpLoad")ResponseBodypublic Map picUpLoad(MultipartFile file, …

linux 用戶創建、管理、權限分配

(1)su與sudo su:通過su可以在用戶之間切換,如果超級權限用戶root向普通或虛擬用戶切換不需要密碼,什么是權力?這就是!而普通用戶切換到其它任何用戶都需要密碼驗證; sudo: sudo扮演的角色注定了…

WebApi路由

路由分為兩種模式:模板路由和特性路由。 模板路由: 模板路由是ASP.NET Web API默認提供的路由。模板路由使用前需要定義路由模板。如下面默認的路由模板: 默認路由的URL格式是api/{controller}/{id}。api代表在資源前面要帶上api目錄&#xf…

HW--漂亮度2(測試通過)

總結:幾個函數的使用 (1) int numInteger.parseInt(str[0]); //將第一個字符串轉成整形數,表示名字個數 (2) String string1str[i].toLowerCase(); //變小寫都 (3) char ch[]strin…

java設計模式 組合_JAVA 設計模式 組合模式

用途組合模式 (Component)將對象組合成樹形結構以表示“部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有唯一性。組合模式是一種結構型模式。結構圖-組合模式結構圖Component: 組合中的對象聲明接口,在適當的情況下,實現所有類共…

項目總結SpringMVC相關

流程文字概述1、用戶發送請求至前端控制器DispatcherServlet2、DispatcherServlet收到請求調用HandlerMapping處理器映射器。3、處理器映射器找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生成)一并返回給DispatcherServlet。4、DispatcherServlet調用Ha…

SpringBoot登錄登出切面開發

閱讀本文約“2.5分鐘” 本文開發環境是SpringBoot2.X版本。 對于系統而言(這里多指管理系統或部分具備登錄登出功能的系統),登錄登出是一個類權限驗證的過程,現在一般是以token進行校驗,即用戶輸入登錄信息&#xff0c…

4、Cocos2dx 3.0三,找一個小游戲開發Hello World 分析

尊重開發人員的勞動成果。轉載的時候請務必注明出處:http://blog.csdn.net/haomengzhu/article/details/27186557Hello World 分析打開新建的"findmistress"項目,能夠看到項目文件是由多個代碼文件及目錄組成的。當中 Hello World 的代碼文件直…

spring --aop(日志記錄)在工程中實際使用

2019獨角獸企業重金招聘Python工程師標準>>> ###1.日志切面 package com.readygo.zbhealth.common;import java.util.Arrays; import java.util.List;import org.aspectj.lang.ProceedingJoinPoint;public class LoggingAspect {public Object Around(ProceedingJoi…

java 多表分頁_多表單獨查詢組合結果的自定義分頁(java代碼)

多表單獨查詢組合結果的自定義分頁實現(java代碼)一、業務需求:遇到一個業務,需要多個表進行分頁查詢,使用union聯合查詢時,速度極其緩慢,即使查詢的字段添加了索引,union查詢好像不走索引,因此…

Neutorn LBaaS 原理

Load Balance as a Service(LBaaS)是 Neutron 提供的一項高級網絡服務。LBaaS 允許租戶在自己的網絡中創建和管理 load balancer。 load balancer 可以說是分布式系統中比較基礎的組件。 它接收前端發來的請求,然后將請求按照某種均衡策略轉發…

判斷一個圖中有無環路的存在

這里要引入兩個概念: 1.樹邊:是一條未被遍歷過的邊,它指向一個未被訪問過的點。 2.反向邊:是一條未被遍歷過的邊,它指向一個被訪問過的點。 如果圖中有環路的存在,那么環路的最后一個邊必然是一條反向邊。 …

精選的一些《編程之美》相關資料

又要到一年的招聘季了,肯定又有很多人開始啃《編程之美》了吧。這本書從開闊視野的角度來說很好,不過限于篇幅,有的問題并沒有講清楚(甚至問題敘述模棱兩可、被標榜為“鼓勵同面試官交流以獲得更多細節”);…

java 內置函數_java8 四大內置核心函數式接口

其他補充接口:一、Consumer:消費型接口(void accept(T t))來看一個簡單得例子:1 /**2 * 消費型接口Consumer3 */4 Test5 public void test1 () {6 consumo(500, (x) -> System.out.println(x));7 }89 public void consumo (double money, …

jQuery - (JQuery datatables api 使用解讀)

學習可參考&#xff1a;http://www.guoxk.com/node/jquery-datatables http://yuemeiqing2008-163-com.iteye.com/blog/2006942 分別導入css和js文件 <link href"~/Content/bootstrap.css" rel"stylesheet" /> <link href"~/Content/datatab…

Tomcat配置JNDI數據源

經過3個多小時的努力&#xff0c;配置JNDI數據源(主要是通過DBCP連接池)終于搞定&#xff5e;還是Tomcat官方的說明好&#xff0c;不過全是英文的&#xff0c;大概還看得懂&#xff0e;百度上那么花花綠綠的太多了&#xff0c;一個也沒成功&#xff01;&#xff0e;&#xff0e…

java 線程池 固定大小_使用Executors服務在Java中創建固定大小線程池的最佳方法...

查看源代碼,您將意識到&#xff1a;Executors.newFixedThreadPool(threadPoolSize);相當于&#xff1a;return new ThreadPoolExecutor(threadPoolSize, threadPoolSize, 0L, MILLISECONDS,new LinkedBlockingQueue());由于它不提供顯式的RejectedExecutionHandler,因此使用默認…

令牌驗證 token

通過令牌驗證在注冊中心控制權限&#xff0c;以決定要不要下發令牌給消費者&#xff0c;可以防止消費者繞過注冊中心訪問提供者&#xff0c;另外通過注冊中心可靈活改變授權方式&#xff0c;而不需修改或升級提供者。 可以全局設置開啟令牌驗證&#xff1a; <!--隨機token令…