Android Java Framework顯示Toast(無Activity和Service)
9人收藏此文章,
我要收藏
發(fā)表于2個月前(2013-07-23 22:16) ,
已有
137次閱讀 ,共
0個評論
最近遇到一個問題是如何在Android Framework中顯示一個提示信息Toast。 從網(wǎng)上查了一下資料,但提供的都是有Activity或者Service的情況。但我的需求是要在一個沒有Activity或者Service的Java文件中去顯示一個Toast。怎么辦呢?因為要創(chuàng)建一個Toast就需要Context,怎樣獲取一個Context呢?苦思冥想沒有找到方法。無奈之下,就先找了一種臨時方案。
臨時方案的做法是寫一個Service,在這個Service中加個提供顯示Toast的接口。將這個Service注冊到ServiceManager中。然后通過ServiceManager去獲取這個Service,調(diào)用這個Service的接口去顯示Toast。這種寫法雖然有效,但感覺很不方便。因為后面有人又遇到這個問題。
后來在Android的源代碼中發(fā)現(xiàn)ActivityThread.currentApplication()可以返回一個Application。通過Application.getApplicationContext()可以獲取一個Context??雌饋硎强尚械摹5珜嶋H試的時候發(fā)現(xiàn)ActivityThread.currentApplication()返回為null。怎么辦呢?通過分析ActivityThread的代碼發(fā)現(xiàn)如果是在非UI thread里面調(diào)用,因為這個時候ActivityThread調(diào)用currentActivityThread返回為null.因此為null.
1 | public static Application currentApplication() { |
2 | ActivityThread am = currentActivityThread(); |
3 | return am != null ? am.mInitialApplication : null ; |
悲劇啊,剛好那支Java文件的API都是運行在非UI thread里面的。那有沒有辦法讓這段代碼運行在UI thread里面呢?
于是苦逼的繼續(xù)查找,終于找到一種方法:
1.通過Looper.getMainLooper()獲取到main looper。在創(chuàng)建一個Handler,在創(chuàng)建Handler的時候?qū)ain looper傳遞給Handler.這樣就可以使這個Handler運行在UI thread中。
2.在Handler的handleMessages()中去調(diào)用ActivityThread.currentApplication()獲取Application。再通過Application.getApplicationContext()獲取到Context。然后創(chuàng)建Toast,顯示。
3.通過Handler.sendMessage的方式去通知Handler顯示一個Toast。
測試,大功告成。
附代碼:
01 | public void connect() { |
02 | Looper looper = Looper.getMainLooper(); |
03 | mHandler = new Handler(looper); |
04 | Message message = mHandler.obtainMessage(SHOW_TOAST); |
05 | mHandler.sendMessage(m); |
08 | public void handleMessage(Message msg) { |
15 | public void showToast() { |
16 | Application application = ActivityThread.currentApplication(); |
17 | Toast.makeText(application.getApplicationContext(), "test test test ....." , Toast.LENGTH_SHORT).show(); |
由于這種做法有點小技巧,不大容易想到,因此記錄在此,供大家查看。