欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JAVA中Context的詳細(xì)介紹和實(shí)例分析

 更新時(shí)間:2020年07月14日 10:33:12   作者:擱淺...  
這篇文章主要介紹了JAVA中Context的詳細(xì)介紹和實(shí)例分析,Context是維持android各組件能夠正常工作的一個(gè)核心功能類(lèi)。如果感興趣來(lái)學(xué)習(xí)一下

最熟悉的陌生人——Context

剛剛學(xué)android或者js等,都會(huì)看見(jiàn)這個(gè)頻繁的字眼——Context。
意為”上下文“。

本文主要記述,Context到底是什么、如何理解Context、一個(gè)APP可以有幾個(gè)Context、Context能干啥、Context的作用域、獲取Context、全局獲取Context技巧。

思考:

Java:萬(wàn)物皆對(duì)象。Flutter:萬(wàn)物皆組件。
俗語(yǔ):”沒(méi)對(duì)象嗎?自己new一個(gè)啊~“
既然大多數(shù)情況可以new一個(gè)實(shí)例,那么,我們?cè)赼ndroid中的Activity實(shí)例怎么獲取呢?Activity.instance可以獲取activity。既然Activity也大致歸屬于一個(gè)類(lèi),那么可不可以用 Activity activity=new Activity(); 呢?安卓不像Java程序一樣,隨便創(chuàng)建一個(gè)類(lèi),寫(xiě)個(gè)main()方法就能運(yùn)行,**Android應(yīng)用模型是基于組件的應(yīng)用設(shè)計(jì)模式,組件的運(yùn)行要有一個(gè)完整的Android工程環(huán)境。在這個(gè)環(huán)境下,Activity、Service等系統(tǒng)組件才能正常工作,而這些組件不能采用普通的java對(duì)象創(chuàng)建方式,new一下是不能創(chuàng)建實(shí)例的,而是要有它們各自的上下文環(huán)境,也就是Context.
所以說(shuō),Context是維持android各組件能夠正常工作的一個(gè)核心功能類(lèi)。

what 's Context:

(本圖為沙拉查詞給出的中文翻譯)

有點(diǎn)晦澀難懂。但在程序中,我們可理解為當(dāng)前對(duì)象在程序中所處的一個(gè)環(huán)境,一個(gè)與系統(tǒng)交互的過(guò)程。 比如QQ和你們自己的女朋友聊天時(shí)(沒(méi)有g(shù)rilfriend的可自己跳過(guò)舉例),此時(shí)的context是指的聊天界面以及相關(guān)的數(shù)據(jù)請(qǐng)求與傳輸,Context在加載資源、啟動(dòng)Activity、獲取系統(tǒng)服務(wù)、創(chuàng)建View等操作都要參與。

所以,一個(gè)Activity就是一個(gè)Context(getActivity()==getContext),一個(gè)Service也是一個(gè)Context。Android把場(chǎng)景抽象為Context類(lèi),用戶和操作系統(tǒng)的每一次交互都是一個(gè)場(chǎng)景,比如:打電話、發(fā)短信等,都有activity,還有一些我們?nèi)庋劭床灰?jiàn)的后臺(tái)服務(wù)。一個(gè)應(yīng)用程序可以認(rèn)為是一個(gè)工作環(huán)境,用戶在這個(gè)環(huán)境中切換到不同的場(chǎng)景,這就像服務(wù)員,客戶可能是外賣(mài)小哥、也可能是農(nóng)民工等,這些就是不同的場(chǎng)景,而服務(wù)員就是一個(gè)應(yīng)用程序。

How to understand the ‘Context':

Context理解為”上下文“/”場(chǎng)景“,可能還是很抽象。那么我們可以做一個(gè)比喻:
一個(gè)APP是仙劍奇?zhèn)b傳3電視劇,Activity、Service、BroadcastReceiver、ContentProvider這四大組件就是電視劇的主角。它們是導(dǎo)演(系統(tǒng))一開(kāi)始就確定好試鏡成功的人。換言之, 不是我們每個(gè)人都能被導(dǎo)演認(rèn)可的。有了演員,就要有鏡頭啊,這個(gè)鏡頭便是(Context)。通過(guò)鏡頭,我們才能看見(jiàn)帥氣 的胡歌。演員們都是在鏡頭(Context環(huán)境)下表演的。那么Button這些組件子類(lèi)型就是配角,它們沒(méi)有那么重要,隨便一個(gè)組件都能參與演出(即隨便new 一個(gè)實(shí)例),但是它們也需要參與鏡頭,不然一部戲只有主角多沒(méi)意思,魔尊重樓還是要的,魔尊也要露面(工作在Context環(huán)境下),所以可以用代碼new Button();或者xml布局定義一個(gè)button。

打開(kāi)AndroidStudio,輸入Context,然后ctrl+鼠標(biāo)左鍵追朔其源碼(看源碼一般都先看注釋便于理解):import android.content.Context;

看注釋?zhuān)琓MD,是English,那么筆者這里就用小學(xué)生英語(yǔ)水平來(lái)翻譯一哈哈:
Context提供了關(guān)于應(yīng)用環(huán)境全局信息的接口。它是一個(gè)abstract類(lèi),它的執(zhí)行被Android系統(tǒng)提供,允許獲取以應(yīng)用為特征的資源和類(lèi)型,是一個(gè)統(tǒng)領(lǐng)一些資源APP環(huán)境變量等的上下文。通過(guò)它可以獲取應(yīng)用程序的資源和類(lèi)(包括應(yīng)用級(jí)別操作,如啟動(dòng)Activity,發(fā)廣播,接收intent等)。abstract會(huì)有它的實(shí)現(xiàn)類(lèi)。在源碼中,我們可以通過(guò)AndroidStudio去查看它的子類(lèi),得到以下關(guān)系:
它有2個(gè)具體實(shí)現(xiàn)子類(lèi):ContextImpl、ContextWrapper。

  • 其中,ContextWrapper類(lèi),只是一個(gè)包裝類(lèi),其構(gòu)造函數(shù)中必須包含一個(gè)Context引用,同時(shí)它提供了attachBaseContext()用于給ContextWrapper對(duì)象中指定真正的Context對(duì)象,調(diào)用它的方法都會(huì)被轉(zhuǎn)向其所包含的真正的Context對(duì)象。
  • ContextThemeWrapper類(lèi)其內(nèi)部包含了與主題相關(guān)的接口。主題就是清單文件中android:theme為Application或Activity元素指定的主題。(Activity才需要主題,Serviceu不需要,因?yàn)榉?wù)是沒(méi)有界面的后臺(tái)場(chǎng)景,所以服務(wù)直接繼承ContextWrapper。Application同理。)而Contextlmpl類(lèi)則是真正實(shí)現(xiàn)了Context中的所有函數(shù),應(yīng)用程序中所調(diào)用的各種Context類(lèi)的方法,其實(shí)現(xiàn)均來(lái)自這個(gè)類(lèi)。
  • 換言之:Context的2個(gè)實(shí)現(xiàn)子類(lèi)分工的,其中ContextImpl是Context的具體是實(shí)現(xiàn)類(lèi),而ContextWrapper則是Context的包裝類(lèi)。Activity、Application、Service都繼承自ContextWrapper(Activity繼承自ContextWrapper的子類(lèi)ContextThemeWrapper),但它們的初始化過(guò)程中都會(huì)創(chuàng)建ContextImpl對(duì)象,由ContextImpl實(shí)現(xiàn)Context中的方法。

How much has Context in a App:

關(guān)鍵在于對(duì)COntext的理解。從上面提到的實(shí)現(xiàn)子類(lèi)可以看出,在APP中,Context的具體實(shí)現(xiàn)子類(lèi)是Acitivity、Service、Applicaiton。所以Context's number=Activity's number + Service's number+1(1個(gè)APP只有一個(gè)Application)。為啥不是4大組件,上面不是說(shuō)四大組件也是主角嗎?看看BroadcastReceiver和ContentProvider的源碼可以知道它們并不是Context的子類(lèi),它們持有的Context都是其他地方傳遞過(guò)去的(比如我們發(fā)送廣播intent中的context就是外部傳遞過(guò)來(lái)的),所以不計(jì)數(shù)它們。

Context's method:

Context哪里會(huì)用到它。剛開(kāi)始了解Android的時(shí)候不知道它是個(gè)啥玩意兒,但是久了發(fā)現(xiàn)有些地方就不得不傳這個(gè)參數(shù)。
比如Toast、啟動(dòng)Activity、啟動(dòng)Service、發(fā)送廣播、操作數(shù)據(jù)庫(kù)等等都需要傳Context參數(shù),具體例子就不說(shuō)了。詳細(xì)可以看后文將提到的如何獲取它。

Context's 作用域

不是隨便獲取一個(gè)Context實(shí)例就可以的,它的使用有一些規(guī)則和限制。因?yàn)镃ontext的具體實(shí)例是由ContextImpl類(lèi)去實(shí)現(xiàn)的,因此,Activity、Service、Application3種類(lèi)型的Context都是等價(jià)的。但是,需要注意的是,,有些場(chǎng)景,比如啟動(dòng)Activity、彈出Dialog等。為了安全,Android不允許Activity或者Dialog憑空出現(xiàn),一個(gè)Activity的啟動(dòng)肯定是由另一個(gè)Activity負(fù)責(zé)的,也就是以此形成的返回棧(具體可以看看任主席的《Android開(kāi)發(fā)藝術(shù)探索》)而Dialog則必須是在一個(gè)Activity上彈出(系統(tǒng)Alert類(lèi)型的Dialog除外),這種情況下, 我們只能用Activity類(lèi)型的Context,否則報(bào)錯(cuò)。

Context作用域 Application Activity Service
Show a Dialog No Yes No
Start an Activity 不推薦 Yes 不推薦
Layout Inflation 不推薦 Yes 不推薦
Start a Service Yes Yes Yes
Send a Broadcast Yes Yes Yes
Register Broadcast Receiver Yes Yes Yes
Load Resource Values Yes Yes Yes

Activity繼承自ContextThemeWrapper,而Application和Service繼承ContextWrapper,所以ContextThemeWrapper在ContextWrapper的基礎(chǔ)上作了一些操作,使得Activity更加厲害。

關(guān)于表格中提到的Application和Service不推薦的2種情況:

1.如果用ApplicationContext去啟動(dòng)一個(gè)LaunchMode為standard的Activity的時(shí)候會(huì)報(bào)錯(cuò):androud,util.AndroidRuntimeException:Calling startActivity from outside of an Activity context require the FLAG_ACTIVITY_NEW_TASK flag。Is this really what you want?
翻譯一下,并了解這個(gè)FLAG的都知道,此時(shí)的非Activity類(lèi)型的Context并沒(méi)有所謂的返回棧,因此帶啟動(dòng)的Activity就找不到棧。它還給我們明確之處了FLAG的解決辦法,這樣啟動(dòng)的時(shí)候就為它創(chuàng)建一個(gè)新的任務(wù)棧,而此時(shí)Activity是以Single Task模式啟動(dòng)的。所以這種用Application Context啟動(dòng)Activity的方式不推薦,Service同理。

2.在Application和Service中去layout inflate也是合法的,但是會(huì)使用系統(tǒng)默認(rèn)的主題樣式,如果自定義了某些樣式可能不會(huì)被使用,所以也不推薦。

注:和UI相關(guān)的,都應(yīng)該使用Activity Context來(lái)處理。其他的一些操作,Service、Activity、Application等實(shí)例都是可以的。同時(shí)要注意Context的引用持有,防止內(nèi)存泄漏。可在被銷(xiāo)毀的時(shí)候,置Context為null。

How to get the ‘Context':

常用4種方法獲取Context對(duì)象:

1.View.getContext():返回當(dāng)前View對(duì)象的Context對(duì)象。通常是當(dāng)前正在展示的Activity對(duì)象。
1.Activity,getApplicationContext()[后文會(huì)詳細(xì)介紹這個(gè)方法]:獲取當(dāng)前Activity所在應(yīng)用進(jìn)程的Context對(duì)象,通常我們使用3.Context對(duì)象時(shí),要優(yōu)先考慮這個(gè)全局的進(jìn)程Context。
ContextWrapper.getBaseContext():用來(lái)獲取一個(gè)ContextWrapper進(jìn)行裝飾之前的Context。實(shí)際開(kāi)發(fā)很少用,也不建議使用。
4.Activity.this:返回當(dāng)前Activity的實(shí)例,如果的UI控件需要使用Activity作為Context對(duì)象,但默認(rèn)的Toast實(shí)際上使用的ApplicationContext也可以。
實(shí)現(xiàn)View.OnClick監(jiān)聽(tīng)方法中,寫(xiě)Toast,不要用this,因?yàn)閠his,在onClick(View view)指的是view對(duì)象而不是Activity實(shí)例,所以在這個(gè)方法中,應(yīng)該使用”當(dāng)前的Activity名.this“,這是入門(mén)者比較容易混淆的地方。

getApplication()和getApplicationContext():
獲取當(dāng)前Application對(duì)象用getApplicationContext.但是getApplication又是什么。
我們可以自己寫(xiě)代碼打印一下:

Application app=(Application)getApplication();
Log.e(TAG,"getApplication is "+app);
Context context=getApplicationContext();
Log.e(TAG,"getApplicationContext is "+ context);

運(yùn)行后看logcat,效果圖就不貼了(電腦卡)。從打印結(jié)果可以看出它們2個(gè)的內(nèi)存地址是相同的,即它們是同一個(gè)對(duì)象。 因?yàn)锳pplication本來(lái)就是一個(gè)Context,那么這里獲取的getApplicationContext()自然也是Application本身的實(shí)例了。那這2個(gè)相同方法存在的意義是啥?(雙胞胎?)實(shí)際上這2個(gè)方法在作用域上有比較大的區(qū)別。 getApplication()一看就知道是用來(lái)獲取Application實(shí)例的(道理可以聯(lián)想getActivity())。但getApplication()只有在Activity和Service中才能調(diào)用的到。 對(duì)于比如BroadcastReceiver等中也想要獲取Application實(shí)例,這時(shí)就需要getApplicationContext()方法。

//繼承BroadcastReceiver并重寫(xiě)onReceive()方法
@Override
public void onReceive(Context context.Intent intent){
 Application app=(Application)context.getApplicationContext();
}

內(nèi)存泄漏之Context:

我們經(jīng)常會(huì)遇到內(nèi)存泄漏,比如Activity銷(xiāo)毀了,但是Context還持有該Activity的引用,造成了內(nèi)存泄漏。(經(jīng)常遇到)

2種典型的錯(cuò)誤引用方式:

1.錯(cuò)誤的單例模式:

public class Singleton{
 private static Singleton instancel
 private Context context;
 private Singleton(Context context){
 this.context=context;
 }
 public static Singleton getInstance(Context context){
 if(instance == null ){
 instance=new Singleton(context);
 }
 return instance;
 }
}

熟悉單例模式的都知道,這是一個(gè)非線程安全的單例模式,instance作為靜態(tài)對(duì)象,其生命周期要長(zhǎng)于普通的對(duì)象(單例直到APP退出后臺(tái)才銷(xiāo)毀),其中也包含了Activity。比如Activity A去getInstance()得到instance對(duì)象,傳入this,常駐內(nèi)存的Singleton保存了我們傳入的A對(duì)象,并一直持有,即使Activity被銷(xiāo)毀掉,但因?yàn)樗囊眠€存在于一個(gè)Singleton中,就不可能被GC掉,這樣就導(dǎo)致了內(nèi)存泄漏。比如典型的數(shù)據(jù)庫(kù)操作,存儲(chǔ)數(shù)據(jù),需要重復(fù)的去索取數(shù)據(jù),用單例保持?jǐn)?shù)據(jù)和拿到Activity持有context引用,因?yàn)閱卫梢钥醋魇巧系?,它幫我們保存?shù)據(jù)。所以即使Activity被finish掉,還有它的引用在Singleton中。

View持有Activity引用:

public class MainActivity extend Activity{
 private static Drawable mDrawable; 
 @Override
 protected void onCreate(Bundle saveInstanceState){
 super.onCreate();
 setContentView(R.layout.activity_main);
 ImageView imageview=new ImageView(this);//通過(guò)代碼動(dòng)態(tài)的創(chuàng)建組件,而不是傳統(tǒng)的xml配置組件,這里的ImageView持有當(dāng)前Activity的引用。
 mDrawable=getResources().getDrawable(R.drawable.ic_launcher);
 imageview.setImageDrawable(mDrawable);
 }
}

上述代碼中,有一個(gè)static的Drawable對(duì)象。當(dāng)ImageView設(shè)置這個(gè)Drawable的時(shí)候,ImageView保存了這個(gè)mDrawable的引用,而ImageView初始化的時(shí)候又傳入了this,此處的this是指MainActivity的context。因?yàn)楸籹tatic修飾的mDrawable是常駐內(nèi)存的(比類(lèi)還要早加載)。MainActivity是它的間接引用了,當(dāng)MainActivity被銷(xiāo)毀的時(shí)候,也不能被GC掉,就造成了內(nèi)存泄漏。

How to get the context in the whole :

大量的地方都需要使用Context,我們常常會(huì)因?yàn)椴恢涝趺吹玫竭@個(gè)Context而苦惱。那么,全局獲取Context無(wú)疑是最好的解決方案。
很多時(shí)候,我們也不是經(jīng)常為得不到Context而發(fā)愁,畢竟我們很多的操作都是在活動(dòng)中進(jìn)行的,而活動(dòng)本身就是一個(gè)Context對(duì)象。但APP架構(gòu)復(fù)雜后,很多邏輯代碼都脫離了Activity類(lèi),此時(shí)又需要使用Context,所以我們需要采取全局獲取Context的方法。
舉例, 我們平常經(jīng)常會(huì)寫(xiě)網(wǎng)絡(luò)工具類(lèi),比如下面的這些代碼:

public calss HttpUtil{
 public static void sendHttpRequest(final String address,final HttpCallbackListener listener){
 new Thread(new Runnable()){
 @Override 
 public void run(){
 HttpURLConnection connection=null;
 try{
 URL url =new URL(address);
 connection=(HttpURLConnection)url.openConnection();
 connection.setRequestMethod("GET");
 connection.setConnectTimeout(8000);
 connection.setReadTimeout(8000);
 connection.setDoInput(true);
 connection.setDoOutput(true);
 InputStream in =connection.getInputStream();
 BufferedReader reader=new BufferedReader(new InputStreamReader(in));
 StringBuilder response=new StringBuilder();
 String line;
 while((line=reader.readLine())!=nulll){
 response.append(line);
 }
 if(listener!=null){
 //回調(diào)onFinish()
 listener.onFinish(response.toString);
 }
 }catch(Execption e){
 if(listener!=null){
 //回調(diào)onError()
 listener.onError(e);
 }
 }finally{
 if(connection!=null){
 connection.disconnect();
 }
 }
 }}.start();
 }
}

上述代碼中使用sendHttpRequest()方法來(lái)發(fā)送HTTP請(qǐng)求顯然沒(méi)問(wèn)題。并且還可以在回調(diào)方法中處理服務(wù)器返回的數(shù)據(jù)。但是這個(gè)方法還可以被優(yōu)化。當(dāng)檢測(cè)不到網(wǎng)絡(luò)存在的時(shí)候就給用戶一個(gè)Toast,并不再執(zhí)行后面的代碼。問(wèn)題來(lái)了,Toast需要一個(gè)Context參數(shù),但是在本來(lái)沒(méi)有可以傳遞的Context對(duì)象。。。
一般思路:在方法中添加一個(gè)COntext參數(shù):

 public static void sendHttpRequest(final String address,final HttpCallbackListener listener,final Context context){
 if(!isNetWorkAvailable()){
 Toast.makeText(context,……);
 ……
 }
 ……

看似可以,但是有點(diǎn)甩鍋。我們將獲取Context的任務(wù)轉(zhuǎn)移到了sendHttpRequest()方法的調(diào)用方。至于調(diào)用方能不能得到COntext對(duì)象就不是我們要考慮的問(wèn)題了。

甩鍋不一定是通用的解決方案。于是這里介紹哈如何獲取全局Context的步驟:,通過(guò)它在項(xiàng)目的任何地方都能輕松的獲取到Context。:

Android提供了一個(gè)Application類(lèi),每當(dāng)APP啟動(dòng)的時(shí)候,系統(tǒng)就會(huì)自動(dòng)將這個(gè)類(lèi)進(jìn)行初始化。我們可以定制一個(gè)自己的Application類(lèi),以便管理程序內(nèi)一些全局的狀態(tài)信息,比如說(shuō)全局Context。
定制一個(gè)自己的Application并不復(fù)雜,首先, 需要?jiǎng)?chuàng)建一個(gè)MyApplication類(lèi)繼承自系統(tǒng)的Application:

public calss MyApplication extends Application{
 private static Context context;
 @Overrride
 public void onCreate(){
 context=getApplicationContext();
 }
 public static Context getContext(){
 return context;
 }
}

代碼很簡(jiǎn)單,容易理解。重寫(xiě)了父類(lèi)的onCreate()方法,并通過(guò)調(diào)用getApplicationContext()方法得到一個(gè)應(yīng)用程序級(jí)別的Context,然后又提供了一個(gè)靜態(tài)的getContext()方法,在這里將剛才獲取到的COntext進(jìn)行返回。

接下來(lái),我們需要告訴系統(tǒng),當(dāng)程序啟動(dòng)的時(shí)候應(yīng)該初始化MyApplication類(lèi),而不是系統(tǒng)默認(rèn)的Application類(lèi)。這一步需要在清單文件里面實(shí)現(xiàn),找到清單文件的<application>標(biāo)簽下進(jìn)行指定就可以了:

<manifest ……
……>
<application 
 android :name="com.example.myContext.MyApplication" //這里輸入.MyApplication也可以,或者輸入MyApplication根據(jù)AS提示自動(dòng)補(bǔ)全包名
 ..>
</application>

注意:這里一定要加上完整的包名,不然系統(tǒng)將無(wú)法找到這個(gè)類(lèi)。

以上就是實(shí)現(xiàn)了一種全局獲取Context的機(jī)制,在這個(gè)項(xiàng)目的任何地方使用Context,只需要調(diào)用MyApplication.getContext()就可以了。

關(guān)于自定義Application和LitePal配置沖突的問(wèn)題:

自定義需要在清單文件寫(xiě)出android.name="……"。而為了讓LitePal可以正常工作,也需要在清單文件下,配置:

android:name="org.litepal.LitePalApplication"

道理也是一樣的,這樣配置后,LitePal就能在內(nèi)部自動(dòng)獲取到Context了。
問(wèn)題:當(dāng)都已經(jīng)配置過(guò)自定義的Application怎么辦?豈不是和LitePalApplication沖突了?
解答:任何一個(gè)項(xiàng)目都只能配置一個(gè)Application. 對(duì)于這種情況,LitePalApplication給出了很簡(jiǎn)單的解決方案,在自定義的Application中去調(diào)用LitePal的初始化方法就可以了:

public calss MyApplication extends Application{
 private static Context context;
 @Overrride
 public void onCreate(){
 context=getApplicationContext();
 LitePalApplication.initialize(context);
 }
 public static Context getContext(){
 return context;
 }
}

這種寫(xiě)法就相當(dāng)于我們把全局Context對(duì)象通過(guò)參數(shù)傳遞給了LitePal,效果和在清單文件配置LitePalApplication是一樣的。

總結(jié),如何在程序中正確的使用Context:

一般Context造成的內(nèi)存泄漏,幾乎都是當(dāng)Context銷(xiāo)毀的時(shí)候,因?yàn)楸灰脤?dǎo)致銷(xiāo)毀失敗。而Application的Context對(duì)象可以簡(jiǎn)單的理解為伴隨著進(jìn)程存在的(它的生命周期也很長(zhǎng),畢竟APP加載的時(shí)候先加載Application,我們可以自定義Application然后繼承系統(tǒng)的Application)。
正確使用:

當(dāng)Applicatin的Context能搞定的情況下,并且生命周期長(zhǎng)的對(duì)象,優(yōu)先使用Application的Context;
不要讓生命周期長(zhǎng)于Activity的對(duì)象持有Activity的引用。
盡量不要在Activity中使用非靜態(tài)內(nèi)部類(lèi)。非靜態(tài)內(nèi)部類(lèi)會(huì)隱式持有外部類(lèi)實(shí)例的引用。如果使用靜態(tài)內(nèi)部類(lèi),將外部實(shí)例引用作為弱引用持有。

獲取全局context的另一種思路:

ActivityThread是主進(jìn)程的入口,它的currentApplication返回值是application.

import android.app.Application;

import java.lang.reflect.InvocationTargetException;

/**
 * 這種方式獲取全局的Application 是一種拓展思路。
 * <p>
 * 對(duì)于組件化項(xiàng)目,不可能把項(xiàng)目實(shí)際的Application下沉到Base,而且各個(gè)module也不需要知道Application真實(shí)名字
 * <p>
 * 這種一次反射就能獲取全局Application對(duì)象的方式相比于在Application#OnCreate保存一份的方式顯示更加通用了
 */
public class AppGlobals {
 private static Application sApplication;

 public static Application getApplication() {
 if (sApplication == null) {
 try {
 sApplication = (Application) Class.forName("android.app.ActivityThread")
 .getMethod("currentApplication")
 .invoke(null, (Object[]) null);
 } catch (IllegalAccessException e) {
 e.printStackTrace();
 } catch (InvocationTargetException e) {
 e.printStackTrace();
 } catch (NoSuchMethodException e) {
 e.printStackTrace();
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 }
 }
 return sApplication;
 }
}

到此這篇關(guān)于Context的詳細(xì)介紹和實(shí)例分析的文章就介紹到這了,更多相關(guān)Context的詳細(xì)介紹內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mybatis Plus 字段為空值時(shí)執(zhí)行更新方法未更新解決方案

    Mybatis Plus 字段為空值時(shí)執(zhí)行更新方法未更新解決方案

    這篇文章主要介紹了Mybatis Plus 字段為空值時(shí)執(zhí)行更新方法未更新解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Java調(diào)用Python腳本傳遞數(shù)據(jù)并返回計(jì)算結(jié)果

    Java調(diào)用Python腳本傳遞數(shù)據(jù)并返回計(jì)算結(jié)果

    實(shí)際工程項(xiàng)目中可能會(huì)用到Java和python兩種語(yǔ)言結(jié)合進(jìn)行,這樣就會(huì)涉及到一個(gè)問(wèn)題,Java如何調(diào)用Python腳本,感興趣的可以了解一下
    2021-05-05
  • IDEA創(chuàng)建Servlet程序的兩種實(shí)現(xiàn)方法

    IDEA創(chuàng)建Servlet程序的兩種實(shí)現(xiàn)方法

    Servlet是JavaWeb應(yīng)用程序中不可或缺的組件之一,本文主要介紹了IDEA創(chuàng)建Servlet程序的兩種實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • maven中更改jdk版本的方法實(shí)現(xiàn)

    maven中更改jdk版本的方法實(shí)現(xiàn)

    本文主要介紹了maven中更改jdk版本的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-07-07
  • Mybatis-Plus打印sql日志兩種方式

    Mybatis-Plus打印sql日志兩種方式

    這篇文章主要給大家介紹了關(guān)于Mybatis-Plus打印sql日志兩種方式,Mybatis-plus是MyBatis增強(qiáng)工具包,用于簡(jiǎn)化CRUD操作,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • SpringData JPA快速上手之關(guān)聯(lián)查詢及JPQL語(yǔ)句書(shū)寫(xiě)詳解

    SpringData JPA快速上手之關(guān)聯(lián)查詢及JPQL語(yǔ)句書(shū)寫(xiě)詳解

    JPA都有SpringBoot的官方直接提供的starter,而Mybatis沒(méi)有,直到SpringBoot 3才開(kāi)始加入到官方模版中,這篇文章主要介紹了SpringData JPA快速上手,關(guān)聯(lián)查詢,JPQL語(yǔ)句書(shū)寫(xiě)的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2023-09-09
  • Java instanceof關(guān)鍵字的的進(jìn)一步理解

    Java instanceof關(guān)鍵字的的進(jìn)一步理解

    這篇文章主要介紹了Java instanceof關(guān)鍵字的的進(jìn)一步理解,本文用一些實(shí)例講解了instanceof操作符的一些知識(shí),需要的朋友可以參考下
    2015-03-03
  • 詳解Java中的mapstruct插件使用

    詳解Java中的mapstruct插件使用

    mapstruct 的插件是專(zhuān)門(mén)用來(lái)處理 domin 實(shí)體類(lèi)與 model 類(lèi)的屬性映射的,我們只需定義 mapper 接口,mapstruct 在編譯的時(shí)候就會(huì)自動(dòng)的幫我們實(shí)現(xiàn)這個(gè)映射接口,避免了麻煩復(fù)雜的映射實(shí)現(xiàn),對(duì)Java?mapstruct使用相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-04-04
  • 關(guān)于Spring注解@Async引發(fā)其他注解失效的解決

    關(guān)于Spring注解@Async引發(fā)其他注解失效的解決

    這篇文章主要介紹了關(guān)于Spring注解@Async引發(fā)其他注解失效的解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • RocketMQ消息隊(duì)列實(shí)現(xiàn)隨機(jī)消息發(fā)送當(dāng)做七夕禮物

    RocketMQ消息隊(duì)列實(shí)現(xiàn)隨機(jī)消息發(fā)送當(dāng)做七夕禮物

    這篇文章主要為大家介紹了RocketMQ消息隊(duì)列實(shí)現(xiàn)隨機(jī)消息發(fā)送當(dāng)做七夕禮物,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08

最新評(píng)論