1. 程式人生 > >親自實踐:.多程序Application onCreate多次執行

親自實踐:.多程序Application onCreate多次執行

最近在使用小米、友盟等推送的時候遇到這樣的問題,就是突然發現Application的onCreate執行了兩遍,所以,針對這一問題,我也進行了一些測試和資料查閱,對於問題原因基本不是那麼模糊了,首先我們來看下為何Application的onCreate會執行兩次:

這樣的程式碼想必並不陌生:

android:process=":remote"

    這裡就不對多程序做太多解釋,':'開頭則為私有程序,只能與本應用互動,若無':',則為全域性程序,在一些許可權配置之後即可實現不同應用與它的互動。

      我是這樣配置的:

<service
android:name=".MyService"
android:process=":remote" android:enabled="true" > </service>
Application中執行
startService(new Intent(this, MyService.class));
MainActivity中
MyApplication.fff.fff = 333;
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
    @Override
public void run() {
        Log.i("Jiaqi", "activity ###### application -> " 
+ getApplicationContext()); Log.i("Jiaqi", "activity ###### numberObj -> " + MyApplication.fff); Log.i("Jiaqi", "activity ###### timer -> " + timer + "->" + MyApplication.fff.fff); } }, 3000, 3000);
MyService中
@Override
public void onCreate() {
    super.onCreate();
Log.i("Jiaqi", "MyService onCreate"
); MyApplication.fff.fff = 555; final Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { Log.i("Jiaqi", "service ###### application -> " + getApplicationContext()); Log.i("Jiaqi", "service ###### numberObj -> " + MyApplication.fff); Log.i("Jiaqi", "service ###### timer -> " + timer + "->" + (MyApplication.fff.fff++)); } }, 3000, 3000); }
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.i("Jiaqi","onStartCommand" + "pid:" + android.os.Process.myPid() + ", a = " + (a++));
    return super.onStartCommand(intent, flags, startId);
}

問題就出在這裡,在Android中,如果有新程序建立,由於程序本身需要一個Application,所以當走到startService時,發現MyService是新程序,所以會新建一個程序放MyService,但MyService又需要一個Application,所以Application會再次執行一遍。 Application onCreate兩次的原因知道了,那隨後的問題又來了,資源是如何分配的呢?

會不會重複載入資源?重複執行方法呢?答案是:會的!以下就是我測試時打印出的log(分兩次列印):

第一次:

I/Jiaqi   ( 2711): Application #####  application -> [email protected]

I/Jiaqi   ( 2711): Application #####  fff -> [email protected]

I/Jiaqi   ( 2744): Application #####  application -> [email protected]

I/Jiaqi   ( 2744): Application #####  fff -> [email protected]

I/Jiaqi   ( 2744): MyService onCreate

I/Jiaqi   ( 2744): onStartCommandpid:2744, a = 0

I/Jiaqi   ( 2744): onStartCommandpid:2744, a = 1

I/Jiaqi   ( 2744): service ###### application -> [email protected]

I/Jiaqi   ( 2744): service ###### numberObj -> [email protected]

I/Jiaqi   ( 2744): service ###### timer -> [email protected]>555

I/Jiaqi   ( 2711): activity ###### application -> [email protected]

I/Jiaqi   ( 2711): activity ###### numberObj -> [email protected]

I/Jiaqi   ( 2711): activity ###### timer -> [email protected]>333

I/Jiaqi   ( 2744): service ###### application -> [email protected]

I/Jiaqi   ( 2744): service ###### numberObj -> [email protected]

I/Jiaqi   ( 2744): service ###### timer -> [email protected]>556

I/Jiaqi   ( 2711): activity ###### application -> [email protected]

I/Jiaqi   ( 2711): activity ###### numberObj -> [email protected]

I/Jiaqi   ( 2711): activity ###### timer -> [email protected]>333

第二次:

I/Jiaqi   ( 2051): application -> [email protected]

/Jiaqi   ( 2051): numberObj -> [email protected]

/Jiaqi   ( 2051): timer -> [email protected]>556I

/Jiaqi   ( 1964): application -> [email protected]

/Jiaqi   ( 1964): numberObj -> [email protected]

/Jiaqi   ( 1964): timer -> [email protected]>333

從以上的log分析,第一次列印時,乍一看,我以為沒有重新建立資源,因為引用都是一樣的,但仔細一看,Application中的fff物件雖然引用一樣,但是MainActivity(主程序)與MyService程序對其操作時,都是各變各的,所以並不是同一塊記憶體區,所以,由於2個程序會有2個虛擬機器執行,MyService程序很可能會複製主程序中的一切,之後再根據自己的操作去操作這塊記憶體,與主程序就沒關係了。這時再看第二次的測試,會發現,果然引用不一樣,所以“複製”也不是每一次都會發生的。

接下來一個問題是  MyService onCreate一次,onStartCommond兩次,這是為何?由於MyService單處一個程序,其程序名就是之前設定的 remote,所以並不會再次建立;onStartCommond呼叫了兩次,因為每次startService都會進入這個回撥,這也充分證明了startService被呼叫了兩次!

所以根據以上分析,做個總結,那就是開發中如遇到多程序(n),那麼在Application中初始化的資源會初始化(n)次,每個程序中都有一份這些物件,不會互相影響。

對於這一問題,我認為當遇到多程序的情況時,初始化需要區分程序:

private boolean shouldInit() {
    ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));
List<ActivityManager.RunningAppProcessInfo> processInfos = am.getRunningAppProcesses();
String mainProcessName = getPackageName();
    int myPid = android.os.Process.myPid();
    for (ActivityManager.RunningAppProcessInfo info : processInfos) {
        Log.i("Jiaqi", "my.pid -> " + myPid + ",mainProcessName -> " + mainProcessName);
Log.i("Jiaqi", "info.pid -> " + info.pid + ",info.processName -> " + info.processName);
        if (info.pid == myPid && mainProcessName.equals(info.processName)) {
            return true;
}
    }
    return false;
}

以上返回true的地方即為主程序。

本人也是初識多程序,如若有問題,請指教!感謝~


相關推薦

親自實踐.程序Application onCreate執行

最近在使用小米、友盟等推送的時候遇到這樣的問題,就是突然發現Application的onCreate執行了兩遍,所以,針對這一問題,我也進行了一些測試和資料查閱,對於問題原因基本不是那麼模糊了,首先我

極限工坊淘小咖程序到底有火?看看這些入駐的企業就知道了

頻繁 部分 改變 開放 實體店 出現 當當 image RoCE 小程序自從去年微信推出之後,最開始大眾的不認同到現在各行業瘋狂入駐,畢竟微信自帶那麽多的流量! 隨著小程序的不斷更新,入口開放的越來越多,讓用戶接觸小程序的方式也變得越來越多,頻繁的更新速度,由此可見騰訊對小

PHP程序初探 --- 利用程序開發點兒東西吧

[原文地址:https://blog.ti-node.com/blog...] 乾巴巴地叨逼叨了這麼久,時候表演真正的技術了! 做個高階點兒的玩意吧,加入我們要做一個任務系統,這個系統可以在後臺幫我們完成一大波(注意是一大波)資料的處理,那麼我們自然想到,多開幾個程序分開處理這些資料,同時我們不能執行了p

簡單的基於Python2.7版本的程序下開發執行緒的示例

簡單的基於Python2.7版本的多程序下開發多執行緒的示例 可以使得程式執行效率至少提升10倍 #!/usr/bin/env python # -*- coding: utf-8 -*- """ @Time : 2018/10/24 @Author : Li

Python 執行緒、程序 (三)之 執行程序對比、程序

Python 多執行緒、多程序 (一)之 原始碼執行流程、GIL Python 多執行緒、多程序 (二)之 多執行緒、同步、通訊 Python 多執行緒、多程序 (三)之 執行緒程序對比、多執行緒 一、多執行緒與多程序的對比 在之前簡單的提過,CPython中的GIL使得同一時刻只能有一個執行緒執行,即併

flask 原始碼淺析(flask 如何處理請求(執行緒,程序,IO路複用))

之前有閱讀過tornado 底層的實現,tornado 為了解決C10K 問題(沒聽說過C10K問題的請檢視: http://www.360doc.com/content/13/0522/18/1542811_287328391.shtml),在Linux 平臺下是使用了epoll(pyth

Python程序程式設計及程序間的通訊,資料傳輸

多程序程式設計及程序間的通訊 意義:充分利用計算機的資源提高程式的運算速率 定義:通過應用程式利用計算機多個核心達到同時執行多個任務的目的,以此提高計算機的執行速率 實施方案:多程序 多執行緒 並行: 計算機同時處理多個任務 併發:同時處理多個任務,核心在不斷的任務間小虎切換,達到好像還都在處理執行的

python 程序,實際上都沒有執行,sleep

思考並行運算的程式碼塊中,是計算密集型的。因為計算的時間複雜度比較高,跑每一個例子會耗費幾天的時間。因此不存在所謂活少人多的問題。 1.是否是程序優先順序的問題 答案為否,因為個程序優先順序一致,而每個程序所需的記憶體量和計算量基本一致,所需執行時間也接近的。 2.是否是程式碼層面的問題 答案為否,因為可

python 程序併發與執行緒併發總結

本文對python支援的幾種併發方式進行簡單的總結。 Python支援的併發分為多執行緒併發與多程序併發(非同步IO本文不涉及)。概念上來說,多程序併發即執行多個獨立的程式,優勢在於併發處理的任務都由作業系統管理,不足之處在於程式與各程序之間的通訊和資料共享不

java封裝FFmpeg命令,支援原生ffmpeg全部命令,實現FFmpeg程序處理與執行緒輸出控制(開啟、關閉、查詢),rtsp/rtmp推流、拉流

前言: 之前已經對FFmpeg命令進行了封裝http://blog.csdn.net/eguid_1/article/details/51787646,但是當時沒有考慮到擴充套件性,所以總體設計不是太好,需要改動的地方也比較多,也不支援原生ffmpeg命令,所以本次版本推翻

【Linux】高併發伺服器模型(程序模型和執行緒模型)

多程序併發伺服器 使用多程序併發伺服器時要考慮以下幾點:             1.      父程序最大檔案描述個數(父程序中需要close關閉accept返回的新檔案描述符)             2.      系統內建立程序個數(與記憶體大小相關)      

python CPU密集型對IO密集型 程序更優於執行緒 GIL

CPU密集型和IO密集型 最近在看Python的多執行緒,經常我們會聽到老手說:“python下多執行緒是雞肋,推薦使用多程序!”,但是為什麼這麼說呢? 要知其然,更要知其所以然。所以有了下面的深入研究: 首先強調背景: 1、GIL是什麼?GIL的全稱是Global I

webpack 打包優化的四種方法(程序打包,程序壓縮,資源 CDN,動態 polyfill)

如今,webpack 毫無疑問是前端構建領域裡最耀眼的一顆星,無論你前端走哪條路線,都需要有很強的webpack 知識。webpack 的基本用法這裡就不展開講了。主要探討一下如何提高 webpack 的打包速度。 這篇文章以 vue cli3.0+,webpack4.0+,nodejs10.0+ 這幾個版

SpringBoot資料來源從庫第一執行SQL很慢的原因

今天開發時偶爾發現從庫的第一次SQL執行的速度很慢,所以就進行了一系列排查,後來發現是因為多資料來源的情況下,從庫都是採用懶載入的形式進行載入的,所以就會出現第一次執行SQL很慢的現象,可以從以下兩點進行證明: 證明一 這是專案剛啟動的時候,主庫進行了初始化: 而當訪問

Android程序app中Application回撥onCreate()方法被執行分析及解決

最近工作中碰到一個問題,在優化app,使用DDMS檢視Application log過程中看到,app啟動了三個程序,一個主程序,兩個附帶的程序。如下圖可看到一個app啟動的三個程序。  自定義Application回撥方法onCreate()被執行了3次。開始不知是何原因。 相

黑馬程序猿——JAVA面向對象的特性封裝,繼承,

面向對象 結構 無法 tex col data- emp ngs 不能 - ----------android培訓、java培訓、java學習型技術博客、期待與您交流!----------

Java程序從命令行接收個數字,求和並輸出結果

程序代碼 ati for right 流程圖 public 技術 參數 由於 程序設計思想:由於命令行接收的是字符串類型,因此應先將字符串類型轉化為整型或其他字符型,然後利用for循環求和並輸出結果 程序流程圖: 源程序代碼: 1 public class Ja

Python 程序並行程式設計實踐: multiprocessing 模組

Python 多程序並行程式設計實踐: multiprocessing 模組 2017/04/17 · 實踐專案 · multiprocessing, 多程序, 並行 本文作者: 伯樂線上 - iPytLab&n

PYTHON——程序Process類

構造方法: Process([group [, target [, name [, args [, kwargs]]]]])   group: 執行緒組,目前還沒有實現,庫引用中提示必須是None;   target: 要執行的方法;   name: 程序名;   args/

Python學習筆記程序

multiprocessing  --程序庫 Linux上可以用fwork,但是windowns不支援fwork,所以才需要用 multiprocessing垮平臺來使用多程序 父程序:當前執行的程序叫父程序 子程序:當前執行的程序中建立的程序叫子程序 引入程序模組 for