(轉)android開發之android:process屬性_application中onCreate執行多次


應用做的匆忙,很多地方只顧實現功能,沒有兼顧好性能,所以停下來重構代碼優化性能,結果在打log看啓動時間的時候,發現

Application的onCreate執行了多次,這樣導致重複初始化資源,初始化了3次導致接近1s時間。


發現這個是由獨立進程引起的。即:process這個屬性。

android:process

 服務所在進程的名字。通常,一個應用的所有組件都運行在系統爲這個應用所創建的默認進程中。這個默認進程是用這個應用的包名來命名的。

 標籤的process屬性可以設置成和所有組件都不同的默認值。但是這些組件可以通過設置自己的process值來覆寫這個默認值,這樣可以讓你的應用跨多進程運行。

如果被設置的進程名是以一個冒號開頭的,則這個新的進程對於這個應用來說是私有的,當它被需要或者這個服務需要在新進程中運行的時候,這個新進程將會被創建。如果這個進程的名字是以小寫字符開頭的,則這個服務將運行在一個以這個名字命名的全局的進程中,當然前提是它有相應的權限。這將允許在不同應用中的各種組件可以共享一個進程,從而減少資源的佔用。

 例如一個應用運行在進程com.aoyousatuo.example中,android:process屬性設置爲com.rabbit.man,則新的進程名字爲com.rabbit.run.


一般情況下一個服務沒有自己獨立的進程,它一般是作爲一個線程運行於它所在的應用的進程中。但是也有例外,Android聲明文件中的android:process屬性卻可以爲任意組件包括應用指定進程,換句話說,通過在聲明文件中設置android:process屬性,我們可以讓組件(例如Activity, Service等)和應用(Application)創建並運行於我們指定的進程中。

如果我們需要讓一個服務在一個遠端進程中運行(而不是標準的它所在的apk的進程中運行),我們可以在聲明文件中這個服務的標籤中通過android:process屬性爲其指定一個進程。

 注意:這裏選擇”remote”這個名字是隨意主觀的,你能用其他名字來讓這個服務在另外的進程中運行。冒號’:’這個前綴將把這個名字附加到你的包所運行的標準進程名字的後面作爲新的進程名稱。比如我這裏有一個百度地圖的服務,設置如下:

   <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":baiduMap" >
        </service>

在DDMS中可以看到這個進程爲

com.example.hello:baiduMap

(如果聲明文件中的組件或者應用沒有指定這個屬性則默認應用和其組件將相應運行在以其包名命名的進程中)


解決方法如下:


@Override
	public void onCreate() {
		super.onCreate();
		mApplication = this;
		long s1 = System.currentTimeMillis();
		String processName = OsUtils.getProcessName(this,
				android.os.Process.myPid());
		L.d(WModel.Time, "進程名稱"+processName);
		if (processName != null) {
			boolean defaultProcess = processName
					.equals(WMapConstants.REAL_PACKAGE_NAME);
			if (defaultProcess) {
				//必要的初始化資源操作
			}
		}
		L.d(WModel.Time, "onCreate耗時" + (System.currentTimeMillis() - s1));
	}

/**
     * @return null may be returned if the specified process not found
     */
    public static String getProcessName(Context cxt, int pid) {
        ActivityManager am = (ActivityManager) cxt.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
        if (runningApps == null) {
            return null;
        }
        for (RunningAppProcessInfo procInfo : runningApps) {
            if (procInfo.pid == pid) {
                return procInfo.processName;
            }
        }
        return null;
    }


這樣一來只初始化一次,不會導致很長時間的浪費。
發佈了22 篇原創文章 · 獲贊 6 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章