A. 安卓的service可以單例嗎
service不需要單例,因為如果已經啟動了服務再次啟動的時候是不會執行onCreate的,只會執行onStart,只會有一個服務
B. android 開發中常用到的設計模式有哪些
設計模式總共是23種,常用的有下面幾種 :
1 單例模式,application 就是單例 可以存儲一些數據例如記錄activity的啟動數量 ;
2 觀察者模式: button的onClickListener ,監聽button的響應;
3 適配器模式 :例如recyclerView 的adapter ;
4 命令模式: 例如開源庫eventBus ,把數據封裝好 發送出去,然後接收; 等等等等,很多
C. android studio單例怎麼使用
android studio使用單例的情況有很多,大多數是工具類,可以使用單例,裡面有很多static方法,很方便的使用這些方法。
D. android 單例模式 什麼時候被殺死 單例的那個對象 什麼時候消失啊
我來補充下樓上:
進程關閉的時機是:
1.用Process.kill或者shell去殺死進程
2.系統通過memory策略來殺死後台進程。
說說第二種吧,當程序按Home鍵或者Back鍵退出後就變做後台進程。
另外,當程序啟動了新的進程。而新的進程進入前台模式,此時程序也變成後台進程。
當前台進程退出,後台進程按照堆棧結構再次呈現時。很可能是個重啟進程的過程,重啟進程意味著單例對象也重新初始化了。這點要尤其謹慎
E. 如何使用android單例模式
java模式之單例模式:
單例模式確保一個類只有一個實例,自行提供這個實例並向整個系統提供這個實例。
特點:
1,一個類只能有一個實例
2,自己創建這個實例
3,整個系統都要使用這個實例
Singleton模式主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。在很多操作中,比如建立目錄
資料庫連接都需要這樣的單線程操作。一些資源管理器常常設計成單例模式。
外部資源:譬如每台計算機可以有若干個列印機,但只能有一個Printer
Spooler,以避免兩個列印作業同時輸出到列印機中。每台計算機可以有若干個通信埠,系統應當集中管理這些通信埠,以避免一個通信埠被兩個請求同時調用。內部資源,譬如,大多數的軟體都有一個(甚至多個)屬性文件存放系統配置。這樣的系統應當由一個對象來管理這些屬性文件。
一個例子:Windows
回收站。
在整個視窗系統中,回收站只能有一個實例,整個系統都使用這個惟一的實例,而且回收站自行提供自己的實例。因此,回收站是單例模式的應用。
兩種形式:
1,餓漢式單例類
public class Singleton {
private Singleton(){}
//在自己內部定義自己一個實例,是不是很奇怪?
//注意這是private 只供內部調用
private static Singleton instance =
new Singleton();
//這里提供了一個供外部訪問本class的靜態方法,可以直接訪問
public static Singleton getInstance() {
return instance;
}
}
2,懶漢式單例類
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton
getInstance() {
//這個方法比上面有所改進,不用每次都進行生成對象,只是第一次
//使用時生成實例,提高了效率!
if (instance==null)
instance=new Singleton();
return instance; }
}
第二中形式是lazy initialization,也就是說第一次調用時初始Singleton,以後就不用再生成了。
注意到lazy
initialization形式中的synchronized,這個synchronized很重要,如果沒有synchronized,那麼使用getInstance()是有可能得到多個Singleton實例。
一般來說第一種比較安全
我自己比較常用的方式:
public class Singleton {
private volatile static
Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton==null){
synchronized(Singleton.class){
if(singleton==null){
singleton=new Singleton();
}
}
}
return singleton;
}
}
F. android之單例模式:懶漢式和餓漢式的區別
比較:
餓漢式是線程安全的,在類創建的同時就已經創建好一個靜態的對象供系統使用,以後不在改變。
懶漢式如果在創建實例對象時不加上synchronized則會導致對對象的訪問不是線程安全的。
G. android service是單例嗎
android service不存在單列的問題,service是安卓一個組件。單例是一種設計模式。
1、在實際運行中同樣的Service的確只能有一個。
2、Service類沒有必要運用單例模式。
H. 安卓的service可以單例嗎
這要看你的service是通過什麼方式啟動的 一:如果你通過startService()方式啟動的話,那麼當你關閉了activity之後 你的service依然還在運行當中。 二:如果你通過bindService()方式啟動的話,那麼他是跟隨activity一起綁定的,那麼也就是說當activity銷毀的時候這個service也跟隨一起銷毀了! 你可以看看 application 這個也挺好使用的 ,可以當做全局的回調對象使用!
I. 結合Android看看單例模式怎麼寫
單例模式常見的兩種實現方式 餓漢模式和 雙重鎖模式
•餓漢模式
public class HungrySingleton {
private static HungrySingleton mInstance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return mInstance;
}
}
不得不說,餓漢模式這個名字起得的確很巧,這種方式,不管你用不用得著這個實例,先給你創建(new)出來,生怕將來創建沒機會似得,完全就是今朝有酒今朝醉的節奏。
與上面對應的還有一種就是懶漢模式,就是在用的時候才在getInstance 方法中完成實例的創建(new),真是「懶」,同時給這個方法添加synchronized 關鍵字,可以確保在多線程情況下單例依舊唯一,但是懶漢模式每次調用getInstance 方法時由於synchronized 的存在,需要進行同步,造成不必要的資源開銷。因此便有了下面雙重鎖模式的實現方式。
•雙重鎖模式(DCL 實現)
public class LazySingleton {
private static LazySingleton mInstance = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (mInstance == null) {
synchronized (LazySingleton.class) {
if (mInstance == null) {
mInstance = new LazySingleton();
}
}
}
return mInstance;
}
}
這樣既避免了餓漢模式的缺點,又解決了懶漢模式的不足;確保單例只在第一次真正需要的時候創建。
Android 中的使用
在日常的Android開發中,也可以見到單例模式的身影。
•Glide
使用Glide載入圖片非常方便,大家應該不陌生,可以看一下它的源碼中單例模式的實現方式。
Glide.with(this).load(url).into(imageView);
//Glide.with()
public static RequestManager with(FragmentActivity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(activity);
}
//RequestManagerRetriever.get()
/** The singleton instance of RequestManagerRetriever. */
private static final RequestManagerRetriever INSTANCE = new RequestManagerRetriever();
/**
* Retrieves and returns the RequestManagerRetriever singleton.
*/
public static RequestManagerRetriever get() {
return INSTANCE;
}
可以看到,當我們寫下Glide.with(..) 這行代碼時,就完成了RequestManagerRetriever 這個類的實例化,這個類的單例模式是使用餓漢模式實現的。
•EventBus
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
};
很明顯,EventBus的單例模式使用雙重鎖模式實現的。
•InputMethodManager static InputMethodManager sInstance
public static InputMethodManager getInstance() {
synchronized (InputMethodManager.class) {
if (sInstance == null) {
IBinder b = ServiceManager.getService(Context.INPUT_METHOD_SERVICE);
IInputMethodManager service = IInputMethodManager.Stub.asInterface(b);
sInstance = new InputMethodManager(service, Looper.getMainLooper());
}
return sInstance;
}
}
InputMethodManager 的單例模式是使用懶漢模式實現。
可以看到,關於單例模式的實現方式,面對不同的場景,我們可以做出不同的選擇
•Glide的單例模式雖然是使用餓漢模式實現,但理論上來說並不會造成內存資源的浪費,因為當我們通過gradle的配置引入Glide的庫時,就是為了載入圖片,必然會使用Glide.with進行相關的操作。同時RequestManagerRetriever 這個類應該是一個網路請求的管理類(Glide源碼沒有研究過,這里只是猜測),這樣的一個類必然需要使用單列模式,試想如果存在多個管理類的實例,那麼談何管理,那麼的多Request到底聽哪個manger 的,這就是前面提到必須使用單列模式的情景。
•EventBus 作為事件匯流排的更要使用單例模式了,如果說EventBus的實例不是單例模式,那麼他就無法實現它的功能了。對於EventBus不了解的同學,可以看看
EventBus 3.0 相見恨晚,EventBus真的很強大。
•InputMethodManager 使用懶漢模式實現單例也是無可厚非的,畢竟誰會去頻繁的獲取那麼多他的實例呢;同時作為一個系統的輸入法管理器,他也必須是唯一的,因此這個類也需要單例模式來實現它唯一的實例供外部使用。
由上可見,關於單例模式的實現,沒有說哪一種方式最好,只有最合適的實現方式;實際開發中,單例模式應該怎麼寫,還需要根據業務場景做最合適的選擇,無論是餓漢懶漢實用才是好漢。個人感覺,餓漢模式是一種簡單又方便的實現方式, 一個類既然已經寫成了單例模式,必然是要使用的呀,誰會去創建一個餓漢模式的單例,又不去使用這個單例呢?
之前在使用Volley的時候,就是使用餓漢模式創建整個應用的RequestQueue單例,所有需要網路請求的地方,把request添加到RequestQueue單例中即可。
public class MyApplication extends Application{
// 建立請求隊列
public static RequestQueue queue;
@Override
public void onCreate() {
super.onCreate();
queue = Volley.newRequestQueue(getApplicationContext());
}
public static RequestQueue getHttpQueue() {
return queue;
}
}
在應用Application的onCreate方法中創建了屬於整個應用的queue,之後每一次網路請求時,只需要queue.add(Request)即可,這里使用單例模式,可以有效的避免在多個地方創建RequestQueue 的實例,浪費系統資源。
J. Android圖形系統(六)-app與SurfaceFlinger服務連接過程
經過上一篇的概覽,我們對Android圖形系統渲染流程有了一個大致的了解,這篇開始做細節分析。那麼先來總結下app與SurfaceFlinger服務連接過程。
經過前面的activity 、window 、view 的分析我們大致了解了Activity的顯示過程。其實Surface的創建過程與Activity的顯示過程密不可分。
那麼就從Activity.makeVisible 開始捋下流程:
1 Activity.makeVisible getWindowManager() 並執行addView。
2 經過WindowManagerImpl 和 WindowManagerGlobal addView , 最終創建了ViewRootImpl
3 ViewRootImpl 內部會new Surface() ,它是一個Parcelable對象,可在進程間傳遞,但目前僅是一個空殼,還未被賦值。
同時,通過WindowManagerGlobal.getWindowSession()獲取了Session實例,准備好了與WMS通信,並且Session內有個成員變數SurfaceSession值得關注,它的初始化是在Session的windowAddedLocked方法,先埋個伏筆。
4 根據流程我們知道,最終ViewRootImpl會在走setView, 在這個方法中開始了兩個流程:
requestLayout執行會走消息,因此它雖然在addToDisplay前面,但是執行是在之後的,因此我們先來看看mWindowSession.addToDisplay,這個過程最終是在WMS執行addWindow方法:
我們之前埋過伏筆的,windowAddedLocked創建了SurfaceSession 對象,並將當前 Session 添加到 WMS.mSessions 成員變數。SurfaceSession 的創建會調用 JNI,在 JNI 調用 nativeCreate()。
從這里開始要細說下了,這是應用程序與SurfaceFlinger建立連接的關鍵點:
跟蹤到android_view_SurfaceSession.cpp 的nativeCreate()方法,創建了SurfaceComposerClient 對象,並且將這個對象賦值給類型為sp<SurfaceComposerClient>的智能指針mSession時,就會導致SurfaceComposerClient類的成員函數onFirstRef被調用:
SurfaceComposerClient類的成員函數getComposerService用來獲得SurfaceFlinger服務的一個代理介面.
ComposerService類是單例模式,當我們第一次調用它的靜態函數getInstance的時候,它就會在構造函數中獲得SurfaceFlinger服務的一個代理介面,並且保存在它的成員變數mComposerService中,同時會通過這個代理介面的成員函數getCblk來獲得一塊匿名共享內存mServerCblkMemory。這塊匿名共享內存是由SurfaceFlinger服務創建的,用來描述系統顯示屏的信息,例如,顯示屏的個數、大小、方向、密度等等信息。
這時候sm有值了,在接著onFirstRef()往下執行:
是不是感覺特別繞,下面來簡單總結下:
首先ComPoserService作為client 與 SurfaceFlinger server進行binder IPC , 獲取到SurfaceFlinger創建的Client對象,它相當於是SurfaceFlinger內部對應用程序客戶端的封裝對象,而Client與SurfaceComposerClient又互為binder ipc的兩端,SurfaceComposerClient為client端,Client為server端。
這樣,應用進程成功通過SurfaceComposerClient與SurfaceFlinger建立了連接。
下篇分析app請求SurfaceFlinger創建Surface過程。
參考:
https://blog.csdn.net/Luoshengyang/article/details/7857163
https://blog.csdn.net/armwind/article/details/73436532