欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

android?sharedUserId?使用知識(shí)盲點(diǎn)解析

 更新時(shí)間:2023年02月15日 08:40:10   作者:Exploring  
這篇文章主要為大家介紹了android?sharedUserId使用的知識(shí)盲點(diǎn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1. 背景

由于在工程中使用了 SPI 機(jī)制,通過 ServiceLoader 的配合來完成模塊間的通信。但是突然收到線上客戶反饋使用了 SDK 后無法進(jìn)行模塊加載,導(dǎo)致部分功能異常。

2. 分析排查

借助客戶提供的測(cè)試包進(jìn)行 debug 調(diào)試,發(fā)現(xiàn)在調(diào)試到 ServiceLoader.load() 方法時(shí)確實(shí)無法加載到對(duì)應(yīng)的模塊配置。查看 ServiceLoader 的狀態(tài)信息如下:

其中的 loader 是 LoadApk$WarningContextClassLoader 對(duì)象,而正常情況下是 DexPathClassLoader。

2.1 查看 ServiceLoader.loader 定義

ServiceLoader API 文檔:developer.android.com/reference/j…

根據(jù)接口定義 load 方法會(huì)根據(jù)指定的 serviceType 創(chuàng)建新的 ServiceLoader 對(duì)象返回,ServiceLoader 內(nèi)部根據(jù)當(dāng)前線程對(duì)應(yīng)的 ContextClassLoader 對(duì)象去加載配置,所以到這里可以分析到 load 方法的加載結(jié)果會(huì)受 ContextClassLoader 的影響,進(jìn)一步推理可能收到插件化、熱修復(fù)等框架影響,確認(rèn)后并沒有使插件化、熱修復(fù)等框架。

2.2 WarningContextClassLoader 為何物?

查找 Android famework 源碼,找到 WarningContextClassLoader 是定義在 LoaderApk 文件中的內(nèi)部類(部分版本是 ActivityThread 類中的內(nèi)部類)。

private void initializeJavaContextClassLoader() {
	IPackageManager pm = ActivityThread.getPackageManager();
	android.content.pm.PackageInfo pi =
			PackageManager.getPackageInfoAsUserCached(
					mPackageName,
					PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
					UserHandle.myUserId());
	if (pi == null) {
		throw new IllegalStateException("Unable to get package info for "
				+ mPackageName + "; is package not installed?");
	}
	/*
	 * Two possible indications that this package could be
	 * sharing its virtual machine with other packages:
	 *
	 * 1.) the sharedUserId attribute is set in the manifest,
	 *     indicating a request to share a VM with other
	 *     packages with the same sharedUserId.
	 *
	 * 2.) the application element of the manifest has an
	 *     attribute specifying a non-default process name,
	 *     indicating the desire to run in another packages VM.
	 */
	boolean sharedUserIdSet = (pi.sharedUserId != null);
	boolean processNameNotDefault =
		(pi.applicationInfo != null &&
		 !mPackageName.equals(pi.applicationInfo.processName));
	boolean sharable = (sharedUserIdSet || processNameNotDefault);
	ClassLoader contextClassLoader =
		(sharable)
		? new WarningContextClassLoader()
		: mClassLoader;
	Thread.currentThread().setContextClassLoader(contextClassLoader);
}
private static class WarningContextClassLoader extends ClassLoader {
	private static boolean warned = false;
	private void warn(String methodName) {
		if (warned) {
			return;
		}
		warned = true;
		Thread.currentThread().setContextClassLoader(getParent());
		Slog.w(ActivityThread.TAG, "ClassLoader." + methodName + ": " +
			  "The class loader returned by " +
			  "Thread.getContextClassLoader() may fail for processes " +
			  "that host multiple applications. You should explicitly " +
			  "specify a context class loader. For example: " +
			  "Thread.setContextClassLoader(getClass().getClassLoader());");
	}
	...
}

在應(yīng)用創(chuàng)建時(shí)會(huì)調(diào)用 ActivityThread 類中的 attach 方法中,attach 方法進(jìn)而調(diào)用 LoadedApk 類中的 makeApplicationInner() 用于創(chuàng)建對(duì)應(yīng)的 Application 對(duì)象。在 makeApplicationInner() 方法的內(nèi)部調(diào)用 initializeJavaContextClassLoader 方法創(chuàng)建對(duì)應(yīng)的 ContentClassLoader 對(duì)象,在 initializeJavaContextClassLoader 方法的內(nèi)部可以看到,如果當(dāng)前 App 在 manifest 中設(shè)置 sharedUserId 屬性,則當(dāng)前應(yīng)用使用的是 WarningContextClassLoader。下面我們就是查看 App 中的配置。

最終驗(yàn)證了我們的猜想,使用 demo 設(shè)置 sharedUserId 屬性問題可正常復(fù)現(xiàn)。

2.3 sharedUserId 屬性

查看官方文檔該屬性配置 API 級(jí)別 29 中已棄用此常量。共享用戶 ID 會(huì)在軟件包管理器中導(dǎo)致具有不確定性的行為。因此,強(qiáng)烈建議您不要使用它,并且我們?cè)谖磥淼?Android 版本中會(huì)將其移除。

2.總結(jié)

排查問題還是比較費(fèi)神,在沒有明顯錯(cuò)誤的時(shí)候,只能針對(duì)每個(gè)可疑的信息去分析,期望發(fā)現(xiàn)蛛絲馬跡。

以上就是android sharedUserId 使用知識(shí)盲點(diǎn)解析的詳細(xì)內(nèi)容,更多關(guān)于android sharedUserId 知識(shí)盲點(diǎn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論