安卓核心程式安裝機制--
每個安裝使用者都知道安卓程式的安裝步驟,下載,點選安裝包,安裝。那麼這些步驟在安卓核心中是如何執行的?我們先從安卓原始碼中的系統軟體PackageInstaller入手,來分析軟體安裝的執行步驟。
PackageInstaller的原始碼packages/apps下。其中的源程式包含如下幾個原始檔:
我們從PackageInstallerActivity入手:
找到oncreate入口:
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
// get intent information
// **首先是從Intent當中讀取包資訊**
final Intent intent = getIntent();
mPackageURI = intent.getData();
mOriginatingURI = intent.getParcelableExtra(Intent.EXTRA_ORIGINATING_URI);
mReferrerURI = intent.getParcelableExtra(Intent.EXTRA_REFERRER);
mPm = getPackageManager();
/* **判斷是否來自未知包源,看是否是非官網上下載下來的APP**
軟體安裝,app-store安裝,普通應用安裝--通過PackageInstallerActivity,Runtime.getRuntime().exec(pm install -r $app)需要安裝許可權
Android應用安裝有如下四種方式
1. 系統應用安裝――開機時完成,沒有安裝介面
2. 網路下載應用安裝――通過market應用完成,沒有安裝介面
3. ADB工具安裝――沒有安裝介面。
4. 第三方應用安裝――通過SD卡里的APK檔案安裝,有安裝介面,由packageinstaller.apk應用處理安裝及解除安裝過程的介面。*/
boolean requestFromUnknownSource = isInstallRequestFromUnknownSource(intent);
安裝包資訊流分析:請移步到1.安裝包資訊流分析
mInstallFlowAnalytics = new InstallFlowAnalytics();
mInstallFlowAnalytics.setContext(this);
mInstallFlowAnalytics.setStartTimestampMillis(SystemClock.elapsedRealtime ());
mInstallFlowAnalytics.setInstallsFromUnknownSourcesPermitted(
isInstallingUnknownAppsAllowed());
mInstallFlowAnalytics.setInstallRequestFromUnknownSource(requestFromUnknownSource);
mInstallFlowAnalytics.setVerifyAppsEnabled(isVerifyAppsEnabled());
mInstallFlowAnalytics.setAppVerifierInstalled(isAppVerifierInstalled());
mInstallFlowAnalytics.setPackageUri(mPackageURI.toString());
//如果連線的開頭不是file或者package,結束安裝
final String scheme = mPackageURI.getScheme();
if (scheme != null && !"file".equals(scheme) && !"package".equals(scheme)) {
Log.w(TAG, "Unsupported scheme " + scheme);
setPmResult(PackageManager.INSTALL_FAILED_INVALID_URI);
mInstallFlowAnalytics.setFlowFinished(
InstallFlowAnalytics.RESULT_FAILED_UNSUPPORTED_SCHEME);
finish();
return;
}
final PackageUtil.AppSnippet as;
if ("package".equals(mPackageURI.getScheme())) {
mInstallFlowAnalytics.setFileUri(false);
try {
mPkgInfo = mPm.getPackageInfo(mPackageURI.getSchemeSpecificPart(),
PackageManager.GET_PERMISSIONS | PackageManager.GET_UNINSTALLED_PACKAGES);
} catch (NameNotFoundException e) {
}
if (mPkgInfo == null) {
Log.w(TAG, "Requested package " + mPackageURI.getScheme()
+ " not available. Discontinuing installation");
showDialogInner(DLG_PACKAGE_ERROR);
setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
mInstallFlowAnalytics.setPackageInfoObtained();
mInstallFlowAnalytics.setFlowFinished(
InstallFlowAnalytics.RESULT_FAILED_PACKAGE_MISSING);
return;
}
as = new PackageUtil.AppSnippet(mPm.getApplicationLabel(mPkgInfo.applicationInfo),
mPm.getApplicationIcon(mPkgInfo.applicationInfo));
} else {
mInstallFlowAnalytics.setFileUri(true);
final File sourceFile = new File(mPackageURI.getPath());
PackageParser.Package parsed = PackageUtil.getPackageInfo(sourceFile);
// Check for parse errors
if (parsed == null) {
Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation");
showDialogInner(DLG_PACKAGE_ERROR);
setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
mInstallFlowAnalytics.setPackageInfoObtained();
mInstallFlowAnalytics.setFlowFinished(
InstallFlowAnalytics.RESULT_FAILED_TO_GET_PACKAGE_INFO);
return;
}
mPkgInfo = PackageParser.generatePackageInfo(parsed, null,
PackageManager.GET_PERMISSIONS, 0, 0, null,
new PackageUserState());
mPkgDigest = parsed.manifestDigest;
as = PackageUtil.getAppSnippet(this, mPkgInfo.applicationInfo, sourceFile);
}
mInstallFlowAnalytics.setPackageInfoObtained();
//set view
setContentView(R.layout.install_start);
mInstallConfirm = findViewById(R.id.install_confirm_panel);
mInstallConfirm.setVisibility(View.INVISIBLE);
PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
mOriginatingUid = getOriginatingUid(intent);
// Block the install attempt on the Unknown Sources setting if necessary.
if ((requestFromUnknownSource) && (!isInstallingUnknownAppsAllowed())) {
//ask user to enable setting first
showDialogInner(DLG_UNKNOWN_APPS);
mInstallFlowAnalytics.setFlowFinished(
InstallFlowAnalytics.RESULT_BLOCKED_BY_UNKNOWN_SOURCES_SETTING);
return;
}
initiateInstall();
}
1.安裝包資訊流分析
相關推薦
安卓核心程式安裝機制--
每個安裝使用者都知道安卓程式的安裝步驟,下載,點選安裝包,安裝。那麼這些步驟在安卓核心中是如何執行的?我們先從安卓原始碼中的系統軟體PackageInstaller入手,來分析軟體安裝的執行步驟。 PackageInstaller的原始碼packages/ap
webapp檢測安卓app是否安裝並launch
nbsp rdo agen bsp 後臺 方法 ins 動態 dev 1. cordova插件 1)查看所有已安裝的安卓app https://www.npmjs.com/package/cordova-plugin-packagemanager A simple p
移動開發----安卓判斷是否安裝了某個APP
1.有的時候我們要呼叫第三方APP。就需要檢視使用者是否安裝了APP。 [java] view plain copy public boo
安卓觸控事件傳遞機制
概述 安卓的觸控事件傳遞大體上是檢視收到事件後進行決定是否要攔截,不攔截可以繼續向內傳遞,攔截了不消費也可以回傳給上層檢視。 事件型別主要有 ACTION_DOWN(按下) ACTION_MOVE(移動) ACTION_UP(擡起) ACTION_C
三種安卓模擬器的安裝和比較
1.google官方的AVD 下載官方的sdk包; 解壓後用sdk manager 下載需要的android版本(如果android官網被牆,可以下載網上整理好的離線包,然後解壓到相應目錄下,也可以設定翻牆代理); 然後執行avd manager,可以安裝需要自定義自己的a
如何在安卓手機裡安裝Lighttpd + php + sqlite3組合
我們都知道,機房裡24小時不停機的計算機是伺服器,而家裡使用的筆記本或桌上型電腦是個人電腦。大部分程式設計師都有個人電腦,筆記本。這些家裡的個人電腦在用的時候開機,用完了就關機,所以,一些需要24小時執行的任務無法放在個人電腦上,只能放在伺服器上執行——即使只是一些小任務
安卓 手寫訊息機制
public class Test { public static void main(String[] args) { MyLooper.prepare(); final MyHandler myHandler1 = new MyHandler("firsthandler",
【分享】安卓手機如何安裝谷歌三件套
之所以分享這篇文章,是因為它不僅適用於小米手機,幾乎適合所有安卓機。 網路上還有其他安裝谷歌服務的方法,但是這種方法能夠不翻牆就安裝三件套,美中不足的是,這個方法有些麻煩。 原理就是,在網站下載好apk,再傳到手機中安裝。 為了方便閱讀,先簡述流程:
Genymotion——安卓系統離線安裝
由於某些緣故,Genymotion線上下載安卓系統速度慢,或者乾脆刷不出下載列表,這裡提供一個離線的方式一鍵匯入系統 這裡提供一個4.2.2的ova檔案 http://pan.baidu.com/s/1i3osu9J 然後拷入這裡目錄 C:\Users\你的使用者名稱\Ap
安卓手機提示安裝包解析失敗的原因及解決方法
4、記憶體卡問題手機記憶體卡的預設格式是FAT,如果你使用電腦將記憶體卡進行格式化時,選擇FAT32的選項,那麼這也可能導致程式安裝處問題。當然還有另外一種可能,就是記憶體卡本身有問題,這個大家試試更換一張記憶體卡試試。 如果不是記憶體卡損壞導致程式無法解析的話,大家可以在手機上對記憶體卡進行格式化(本人親測
一起學微軟Power BI系列-使用技巧(3)Power BI安卓手機版安裝與體驗
Power BI有手機版,目前支援安卓,蘋果和WP,不過沒有WP手機,蘋果在國內還不能用,要FQ和用就不測試了。安卓的我也也是費了九牛二虎之力才把app下載下來,把方法分享給大家。 FQ太麻煩,所以建議大家不要用了。同時我也使用了很多第三方的線上網站下載google商店的app工具,結果
4.3 安卓應用程式簽名
11 本文主要講解Android應用程式簽名相關的理論知識,包括:什麼是簽名、為什麼要給應用程式簽名、如何給應用程式簽名等。 1、什麼是簽名? 如果這個問題不是放在Android開發中來問,如果是放在一個普通的版塊,我想大家都知道簽名的含義。可往往就是將一些生
安卓減小APP安裝包的大小
目錄 一、分析app大小 1.使用Android Studio2.2新功能直接分析APK的大小 Build > Analyz APK Paste_Image.png 2.各個檔案介紹 assets:存放一些配置檔案res:資原始檔,圖片、字串、x
安卓開發之訊息機制和AsyncTask實現的基本原理
一、基本概述 在Android中,只可以在UiThread(UI主執行緒)才可以直接更新介面,不然會丟擲異常。 WHY: 防止多個執行緒來修改介面,導致混亂 通過同步鎖來防止介面混亂會導致效能降低 。
通過Html網頁呼叫本地安卓app程式程式碼
前段時間寫一些移動端的專案,正好專案中遇到與native互動的需求,特此將其整理下來: 一. 通過html頁面開啟Android本地的app 首先在編寫一個簡單的html頁面 <html> <head>
Android6.0安卓核心對MPTCP協議的支援
MPTCP IETF工作組的官方網站上實現了安卓4.4.4對MPTCP協議的支援,但是,安卓4.4.4已經是非常古老的安卓版本,官網所推薦的Nexus5也是較為古老的機型,進行測試時會經常出現卡頓的情況,並且,Nexus5在中國僅支援中國聯通的4G網路制式,以上
淺談安卓系統記憶體執行機制
Dalvik虛擬機器作為Android平臺的核心組成部分之一,允許在有限的記憶體資源中同時執行多個虛擬機器例項。Dalvik虛擬機器通過以下方式提升效能: 1、DEX程式碼安裝時或第一次動態載入時odex化處理。 2、Android2.2版本提供了JIT機制提升效
安卓開發之IPC機制
其實幾乎任何一款作業系統都有 IPC 機制,那麼什麼叫做 IPC 機制呢 —— Inter-Process Communication(程序間通訊或跨程序通訊,不懂程序與執行緒的請自行百度) 下面簡單介紹 windows 、 linux 以及
安卓開發-軟體安裝-環境配置
使用JAVA語言,eclipse程式設計工具。安裝包有:eclipse_32&64,jdk6-x64,android-sdk,ADT-15.0.0。1.先安裝JDK,直接選擇個路徑安裝,建議這幾個軟體全放在一個資料夾內,我的路徑是:D:\Develop\Java\
安卓核心驅動編譯的方法——自我感悟
學習linux的時候,一般有兩種方法。一種是配置Kconfig與Makefile檔案,接著使用make menuconfig來實現核心的新增。還有一種是將驅動編譯為.ko檔案,通過insmod的方式來載入。 可最近在編譯安卓原始碼,發現這樣子行不通。當讓,第二種方法是可以的