(一)intent查詢與匹配
android使用intent進行元件,程序之間的通訊和跳轉。intent具有隱式intent和顯式intent兩種,android系統通過packagemanagerservice來進行系統元件的維護。
packagemanagerservice的建構函式大概有700多行,它載入了系統已安裝的各類apk,並載入了framework資源和核心庫。載入了資源和核心庫之後才開始對掃瞄的指定目錄下的apk檔案進行解析。實現這一操作的**是scandirli函式。
private void scandirli(file dir, final int parseflags, int scanflags, long currenttime)
if (debug_package_scanning)
for (file file : files)
try catch (packagemanagerexception e) }}
}
其中scanpackagetracedli實現了包掃瞄
private packageparser.package scanpackagetracedli(file scanfile, final int parseflags,
int scanflags, long currenttime, userhandle user) throws packagemanagerexception finally
}
private packageparser.package scanpackageli(file scanfile, int parseflags, int scanflags,
long currenttime, userhandle user) throws packagemanagerexception
trace.tracebegin(trace_tag_package_manager, "parsepackage");
final packageparser.package pkg;
try catch (packageparserexception e) finally
return scanpackageli(pkg, scanfile, parseflags, scanflags, currenttime, user);
}
在scanpackageli方法中,系統會構建乙個packageparser(包解析器),並呼叫這個包解析器的parsepackage方法進行檔案解析。
public package parsepackage(file packagefile, int flags) throws packageparserexception else
}
這個方法會根據是否只有乙個apk,分別呼叫不同的方法進行解析。
無論是parseclusterpackage還是parsemonolithicpackage方法,其中都呼叫到了parsebaseapk方法。這個方法才具體實現了解析乙個androidmanifest.xml檔案的流程。
private package parsebaseapk(resources res, xmlresourceparser parser, int flags,
string outerror) throws xmlpullparserexception, ioexception
} catch (packageparserexception e)
final package pkg = new package(pkgname);
typedarray sa = res.obtainattributes(parser,
com.android.internal.r.styleable.androidmanifest);
com.android.internal.r.styleable.androidmanifest_versioncode, 0);
pkg.baserevisioncode = sa.getinteger(
com.android.internal.r.styleable.androidmanifest_revisioncode, 0);
pkg.mversionname = sa.getnonconfigurationstring(
com.android.internal.r.styleable.androidmanifest_versionname, 0);
if (pkg.mversionname != null)
sa.recycle();
return parsebaseapkcommon(pkg, null, res, parser, flags, outerror);
}
可以清晰地看到它解析了apk的versionname,versioncode,baseversioncode。那麼apk的各個元件是在**解析的呢?
xmlresourceparser parser, int flags, string outerror)
owner.activities.add(a);
} else if (tagname.equals("receiver"))
owner.receivers.add(a);
} else if (tagname.equals("service"))
owner.services.add(s);
} else if (tagname.equals("provider"))
owner.providers.add(p);
}// **省略
}顯而易見,這裡系統將應用的各個元件解析出來,並且存入到了各個集合當中。
至此,整個資訊樹構建完畢,系統已經儲存好了這個應用的元件資訊。
(二)資訊匹配
我們看一下呼叫intent的具體方法,一般情況下,我們都是使用startactivity這個方法的。我們跟進去看一下。
@override
public void startactivity(intent intent, @nullable bundle options) else
}
然後我們在看一下startactivityforresult方法。
//省略**
options = transferspringboardactivityoptions(options);
instrumentation.activityresult ar =
minstrumentation.execstartactivity(
intent, requestcode, options);
if (ar != null)
//省略**
其中核心**是execstartactivity這個方法。
這個方法經過一系列呼叫,最終呼叫了resolveactivityinfo方法
public activityinfo resolveactivityinfo(@nonnull packagemanager pm,
@packagemanager.componentinfoflags int flags) catch (packagemanager.namenotfoundexception e)
} else
}return ai;
}
這個方法會根據傳進來的flags在pms所儲存的元件列表中挑選最合適的系統元件,進行回傳。
因此整個流程就是:
在系統啟動時,packagemanagerservice就會啟動,pms將解析所有已安裝的應用資訊,構建資訊表,當使用者通過intent跳轉到某個元件時,會根據intent中包含的資訊到pms中查詢對應的元件列表,最後跳轉到目標元件當中。
Fabric 原始碼解析 原始碼目錄解析
這裡對重要的一些目錄進行說明 bccsp 與密碼學 加密 簽名 證書等等 相關的加密服務 將fabric中用到的密碼學相關的函式抽象成了一組介面,便於拓展。bddtests 一種新型的軟體開發模式 行為驅動開 需求 開發 common 一些公共庫 錯誤處理 日誌處理 賬本儲存 策略以及各種工具等等 ...
Spring原始碼解析之 Aop原始碼解析(2)
spring aop 更多的是oop開發模式的乙個補充,幫助oop以更好的方式來解決對於需要解決業務功能模組之上統一管理 的功能 以一副圖來做為aop功能的說明更直觀些。對於類似系統的安全檢查,系統日誌,事務管理等相關功能,物件導向的開發方法並沒有更好的解決方法 aop引入了一些概念。更多的是spr...
weex原始碼解析(四) android引入sdk
上一章,我們簡單說明了下js檔案的生成。那本篇文章,會先簡單使用下這個sdk,將上一章生成的js檔案,進行載入,以便頁面展示手機端上。compile com.android.support recyclerview v7 23.1.1 compile com.android.support supp...