<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                **應用程序包的安裝是android的特點** APK為AndroidPackage的縮寫 Android應用安裝有如下四種方式: 1.系統應用安裝――開機時完成,沒有安裝界面 2.網絡下載應用安裝――通過market應用完成,沒有安裝界面 3.ADB工具安裝――沒有安裝界面。 4.第三方應用安裝――通過SD卡里的APK文件安裝,有安裝界面,由???????? packageinstaller.apk應用處理安裝及卸載過程的界面。 應用安裝的流程及路徑? 應用安裝涉及到如下幾個目錄:???????? system/app?---------------系統自帶的應用程序,獲得adb?root權限才能刪除 data/app??---------------用戶程序安裝的目錄。安裝時把??????????????????????????????????????????????????????????????????????????????????????????????????????apk文件復制到此目錄 data/data?---------------存放應用程序的數據 data/dalvik-cache--------將apk中的dex文件安裝到dalvik-cache目錄下(dex文件是dalvik虛擬機的可執行文件,其大小約為原始apk文件大小的四分之一) 安裝過程: 復制APK安裝包到data/app目錄下,解壓并掃描安裝包,把dex文件(Dalvik字節碼)保存到dalvik-cache目錄,并data/data目錄下創建對應的應用數據目錄。 卸載過程: 刪除安裝過程中在上述三個目錄下創建的文件及目錄。 安裝應用的過程解析 一.開機安裝? PackageManagerService處理各種應用的安裝,卸載,管理等工作,開機時由systemServer啟動此服務 (源文件路徑:android\frameworks\base\services\java\com\android\server\PackageManagerService.java) PackageManagerService服務啟動的流程: 1.首先掃描安裝“system\framework”目錄下的jar包 ~~~ //?Find?base?frameworks?(resource?packages?without?code).?? ???????????mFrameworkInstallObserver?=?new?AppDirObserver(?? ???????????????mFrameworkDir.getPath(),?OBSERVER_EVENTS,?true);?? ???????????mFrameworkInstallObserver.startWatching();?? ???????????scanDirLI(mFrameworkDir,?PackageParser.PARSE_IS_SYSTEM?? ???????????????????|?PackageParser.PARSE_IS_SYSTEM_DIR,?? ???????????????????scanMode?|?SCAN_NO_DEX,?0);?? ~~~ 2.掃描安裝系統system/app的應用程序 ~~~ //?Collect?all?system?packages.?? ??????????mSystemAppDir?=?new?File(Environment.getRootDirectory(),?"app");?? ??????????mSystemInstallObserver?=?new?AppDirObserver(?? ??????????????mSystemAppDir.getPath(),?OBSERVER_EVENTS,?true);?? ??????????mSystemInstallObserver.startWatching();?? ??????????scanDirLI(mSystemAppDir,?PackageParser.PARSE_IS_SYSTEM?? ??????????????????|?PackageParser.PARSE_IS_SYSTEM_DIR,?scanMode,?0);?? ~~~ 3.制造商的目錄下/vendor/app應用包 ~~~ //?Collect?all?vendor?packages.?? ???????????mVendorAppDir?=?new?File("/vendor/app");?? ???????????mVendorInstallObserver?=?new?AppDirObserver(?? ???????????????mVendorAppDir.getPath(),?OBSERVER_EVENTS,?true);?? ???????????mVendorInstallObserver.startWatching();?? ???????????scanDirLI(mVendorAppDir,?PackageParser.PARSE_IS_SYSTEM?? ???????????????????|?PackageParser.PARSE_IS_SYSTEM_DIR,?scanMode,?0);?? ~~~ 4.掃描“data\app”目錄,即用戶安裝的第三方應用 ~~~ scanDirLI(mAppInstallDir,?0,?scanMode,?0);?? ~~~ 5.掃描"?data\app-private"目錄,即安裝DRM保護的APK文件(一個受保護的歌曲或受保 護的視頻是使用?DRM?保護的文件) ~~~ scanDirLI(mDrmAppPrivateInstallDir,?PackageParser.PARSE_FORWARD_LOCK,?? ????????????????????scanMode,?0);?? ~~~ 掃描方法的代碼清單 ~~~ private?void?scanDirLI(File?dir,?int?flags,?int?scanMode,?long?currentTime)?{?? ????????String[]?files?=?dir.list();?? ????????if?(files?==?null)?{?? ????????????Log.d(TAG,?"No?files?in?app?dir?"?+?dir);?? ????????????return;?? ????????}?? ????????if?(false)?{?? ????????????Log.d(TAG,?"Scanning?app?dir?"?+?dir);?? ????????}?? ????????int?i;?? ????????for?(i=0;?i<files.length;?i++)?{?? ????????????File?file?=?new?File(dir,?files[i]);?? ????????????if?(!isPackageFilename(files[i]))?{?? ????????????????//?Ignore?entries?which?are?not?apk's?? ????????????????continue;?? ????????????}?? ????????????PackageParser.Package?pkg?=?scanPackageLI(file,?? ????????????????????flags|PackageParser.PARSE_MUST_BE_APK,?scanMode,?currentTime);?? ????????????//?Don't?mess?around?with?apps?in?system?partition.?? ????????????if?(pkg?==?null?&&?(flags?&?PackageParser.PARSE_IS_SYSTEM)?==?0?&&?? ????????????????????mLastScanError?==?PackageManager.INSTALL_FAILED_INVALID_APK)?{?? ????????????????//?Delete?the?apk?? ????????????????Slog.w(TAG,?"Cleaning?up?failed?install?of?"?+?file);?? ????????????????file.delete();?? ????????????}?? ????????}?? ????}?? ~~~ 并且從該掃描方法中可以看出調用了scanPackageLI() private?PackageParser.Package?scanPackageLI(File?scanFile, int?parseFlags,?int?scanMode,?long?currentTime) 跟蹤scanPackageLI()方法后發現,程序經過很多次的if?else?的篩選,最后判定可以安裝后調用了?mInstaller.install ~~~ if?(mInstaller?!=?null)?{?? ????????????????????int?ret?=?mInstaller.install(pkgName,?useEncryptedFSDir,??pkg.applicationInfo.uid,pkg.applicationInfo.uid);?? ????????????????????if(ret?<?0)?{?? ????????????????????????//?Error?from?installer?? ????????????????????????mLastScanError?=????PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;?? ????????????????????????return?null;?? ????????????????????}?? ????????????????}?? mInstaller.install()??通過???? ??LocalSocketAddress?address?=?new?LocalSocketAddress( ????????????????"installd",?LocalSocketAddress.Namespace.RESERVED); ~~~ 指揮installd在C語言的文件中完成工作 PackageManagerService小節?:1)從apk,?xml中載入pacakge信息,?存儲到內部成員變量中,?用于后面的查找.?關鍵的方法是scanPackageLI(). 2)各種查詢操作,?包括query?Intent操作. 3)install?package和delete?package的操作.?還有后面的關鍵方法是installPackageLI(). 二、從網絡上下載應用: 下載完成后,會自動調用Packagemanager的安裝方法installPackage() /*?Called?when?a?downloaded?package?installation?has?been?confirmed?by?the?user?*/ 由英文注釋可見PackageManagerService類的installPackage()函數為安裝程序入口。 ~~~ public?void?installPackage(?? ???????????final?Uri?packageURI,?final?IPackageInstallObserver?observer,?final?int?flags,?? ???????????final?String?installerPackageName)?{?? ???????mContext.enforceCallingOrSelfPermission(?? ???????????????android.Manifest.permission.INSTALL_PACKAGES,?null);?? ???????Message?msg?=?mHandler.obtainMessage(INIT_COPY);?? ???????msg.obj?=?new?InstallParams(packageURI,?observer,?flags,?? ???????????????installerPackageName);?? ???????mHandler.sendMessage(msg);?? ???}?? ~~~ 其中是通過PackageHandler的實例mhandler.sendMessage(msg)把信息發給繼承Handler的類HandleMessage()方法 ~~~ class?PackageHandler?extends?Handler{?? ??????????????????? *****************省略若干********************?? ?????????public?void?handleMessage(Message?msg)?{?? ????????????try?{?? ????????????????doHandleMessage(msg);?? ????????????}?finally?{?? ????????????????Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);?? ????????????}?? ????????}?? ???******************省略若干**********************?? ?}?? ~~~ 把信息發給doHandleMessage()方法,方法中用switch()語句進行判定傳來Message ~~~ ?void?doHandleMessage(Message?msg)?{?? ????????????switch?(msg.what)?{?? ????????????? ????????????????case?INIT_COPY:?{?? ????????????????????if?(DEBUG_SD_INSTALL)?Log.i(TAG,?"init_copy");?? ????????????????????HandlerParams?params?=?(HandlerParams)?msg.obj;?? ????????????????????int?idx?=?mPendingInstalls.size();?? ????????????????????if?(DEBUG_SD_INSTALL)?Log.i(TAG,?"idx="?+?idx);?? ????????????????????//?If?a?bind?was?already?initiated?we?dont?really?? ????????????????????//?need?to?do?anything.?The?pending?install?? ????????????????????//?will?be?processed?later?on.?? ????????????????????if?(!mBound)?{?? ????????????????????????//?If?this?is?the?only?one?pending?we?might?? ????????????????????????//?have?to?bind?to?the?service?again.?? ????????????????????????if?(!connectToService())?{?? ????????????????????????????Slog.e(TAG,?"Failed?to?bind?to?media?container?service");?? ????????????????????????????params.serviceError();?? ????????????????????????????return;?? ????????????????????????}?else?{?? ????????????????????????????//?Once?we?bind?to?the?service,?the?first?? ????????????????????????????//?pending?request?will?be?processed.?? ????????????????????????????mPendingInstalls.add(idx,?params);?? ????????????????????????}?? ????????????????????}?else?{?? ????????????????????????mPendingInstalls.add(idx,?params);?? ????????????????????????//?Already?bound?to?the?service.?Just?make?? ????????????????????????//?sure?we?trigger?off?processing?the?first?request.?? ????????????????????????if?(idx?==?0)?{?? ????????????????????????????mHandler.sendEmptyMessage(MCS_BOUND);?? ????????????????????????}?? ????????????????????}?? ????????????????????break;?? ????????????????}?? ????????????????case?MCS_BOUND:?{?? ????????????????????if?(DEBUG_SD_INSTALL)?Log.i(TAG,?"mcs_bound");?? ????????????????????if?(msg.obj?!=?null)?{?? ????????????????????????mContainerService?=?(IMediaContainerService)?msg.obj;?? ????????????????????}?? ????????????????????if?(mContainerService?==?null)?{?? ????????????????????????//?Something?seriously?wrong.?Bail?out?? ????????????????????????Slog.e(TAG,?"Cannot?bind?to?media?container?service");?? ????????????????????????for?(HandlerParams?params?:?mPendingInstalls)?{?? ????????????????????????????mPendingInstalls.remove(0);?? ????????????????????????????//?Indicate?service?bind?error?? ????????????????????????????params.serviceError();?? ????????????????????????}?? ????????????????????????mPendingInstalls.clear();?? ????????????????????}?else?if?(mPendingInstalls.size()?>?0)?{?? ????????????????????????HandlerParams?params?=?mPendingInstalls.get(0);?? ????????????????????????if?(params?!=?null)?{?? ????????????????????????????params.startCopy();?? ????????????????????????}?? ????????????????????}?else?{?? ????????????????????????//?Should?never?happen?ideally.?? ????????????????????????Slog.w(TAG,?"Empty?queue");?? ????????????????????}?? ????????????????????break;?? ????????????????}?? ????????????****************省略若干**********************?? }?? }??????????????? ~~~ public?final?boolean?sendMessage?([Message](http://developer.android.com/reference/android/os/Message.html)?msg) public?final?boolean?sendEmptyMessage?(int?what) 兩者參數有別。 然后調用抽象類HandlerParams中的一個startCopy()方法 ~~~ abstract?class?HandlerParams?{ final?void?startCopy()?{ ???***************若干if語句判定否這打回handler消息******* handleReturnCode(); } } ~~~ handleReturnCode()復寫了兩次其中有一次是刪除時要調用的,只列出安裝調用的一個方法 ~~~ @Override?? ???????void?handleReturnCode()?{?? ???????????//?If?mArgs?is?null,?then?MCS?couldn't?be?reached.?When?it?? ???????????//?reconnects,?it?will?try?again?to?install.?At?that?point,?this?? ???????????//?will?succeed.?? ???????????if?(mArgs?!=?null)?{?? ???????????????processPendingInstall(mArgs,?mRet);?? ???????????}?? ???????}?? ~~~ 這時可以清楚的看見?processPendingInstall()被調用。 其中run()方法如下 ~~~ run(){?? synchronized?(mInstallLock)?{?? ????????????????????????************省略*****************?? ????????????????????????installPackageLI(args,?true,?res);?? ????????????????????? ?}?? }?? instaPacakgeLI()args,res參數分析?? ~~~ ----------------------------------------------------------------------------------------- //InstallArgs?是在PackageService定義的static?abstract?class?InstallArgs?靜態抽象類。 ~~~ static?abstract?class?InstallArgs?{?? *********************************************************************?? 其中定義了flag標志,packageURL,創建文件,拷貝apk,修改包名稱,?? ????????????????????還有一些刪除文件的清理,釋放存儲函數。?? ????*********************************************************************?? }?? ??class?PackageInstalledInfo?{?? ????????String?name;?? ????????int?uid;?? ????????PackageParser.Package?pkg;?? ????????int?returnCode;?? ????????PackageRemovedInfo?removedInfo;?? ?}?? ~~~ ----------------------------------------------------------------------------------------- ~~~ private?void?installPackageLI(InstallArgs?args,?? ??????????boolean?newInstall,?PackageInstalledInfo?res)?{?? ??????int?pFlags?=?args.flags;?? ??????String?installerPackageName?=?args.installerPackageName;?? ??????File?tmpPackageFile?=?new?File(args.getCodePath());?? ??????boolean?forwardLocked?=?((pFlags?&?PackageManager.INSTALL_FORWARD_LOCK)?!=?0);?? ??????boolean?onSd?=?((pFlags?&?PackageManager.INSTALL_EXTERNAL)?!=?0);?? ??????boolean?replace?=?false;?? ??????int?scanMode?=?(onSd???0?:?SCAN_MONITOR)?|?SCAN_FORCE_DEX?|?SCAN_UPDATE_SIGNATURE?? ??????????????|?(newInstall???SCAN_NEW_INSTALL?:?0);?? ??????//?Result?object?to?be?returned?? ??????res.returnCode?=?PackageManager.INSTALL_SUCCEEDED;?? ??????//?Retrieve?PackageSettings?and?parse?package?? ??????int?parseFlags?=?PackageParser.PARSE_CHATTY?|?? ??????(forwardLocked???PackageParser.PARSE_FORWARD_LOCK?:?0)?|?? ??????(onSd???PackageParser.PARSE_ON_SDCARD?:?0);?? ??????parseFlags?|=?mDefParseFlags;?? ??????PackageParser?pp?=?new?PackageParser(tmpPackageFile.getPath());?? ??????pp.setSeparateProcesses(mSeparateProcesses);?? ??????final?PackageParser.Package?pkg?=?pp.parsePackage(tmpPackageFile,?? ??????????????null,?mMetrics,?parseFlags);?? ??????if?(pkg?==?null)?{?? ??????????res.returnCode?=?pp.getParseError();?? ??????????return;?? ??????}?? ??????String?pkgName?=?res.name?=?pkg.packageName;?? ??????if?((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY)?!=?0)?{?? ??????????if?((pFlags&PackageManager.INSTALL_ALLOW_TEST)?==?0)?{?? ??????????????res.returnCode?=?PackageManager.INSTALL_FAILED_TEST_ONLY;?? ??????????????return;?? ??????????}?? ??????}?? ??????if?(GET_CERTIFICATES?&&?!pp.collectCertificates(pkg,?parseFlags))?{?? ??????????res.returnCode?=?pp.getParseError();?? ??????????return;?? ??????}?? ??????//?Get?rid?of?all?references?to?package?scan?path?via?parser.?? ??????pp?=?null;?? ??????String?oldCodePath?=?null;?? ??????boolean?systemApp?=?false;?? ??????synchronized?(mPackages)?{?? ??????????//?Check?if?installing?already?existing?package?? ??????????if?((pFlags&PackageManager.INSTALL_REPLACE_EXISTING)?!=?0)?{?? ??????????????String?oldName?=?mSettings.mRenamedPackages.get(pkgName);?? ??????????????if?(pkg.mOriginalPackages?!=?null?? ??????????????????????&&?pkg.mOriginalPackages.contains(oldName)?? ??????????????????????&&?mPackages.containsKey(oldName))?{?? ??????????????????//?This?package?is?derived?from?an?original?package,?? ??????????????????//?and?this?device?has?been?updating?from?that?original?? ??????????????????//?name.??We?must?continue?using?the?original?name,?so?? ??????????????????//?rename?the?new?package?here.?? ??????????????????pkg.setPackageName(oldName);?? ??????????????????pkgName?=?pkg.packageName;?? ??????????????????replace?=?true;?? ??????????????}?else?if?(mPackages.containsKey(pkgName))?{?? ??????????????????//?This?package,?under?its?official?name,?already?exists?? ??????????????????//?on?the?device;?we?should?replace?it.?? ??????????????????replace?=?true;?? ??????????????}?? ??????????}?? ??????????PackageSetting?ps?=?mSettings.mPackages.get(pkgName);?? ??????????if?(ps?!=?null)?{?? ??????????????oldCodePath?=?mSettings.mPackages.get(pkgName).codePathString;?? ??????????????if?(ps.pkg?!=?null?&&?ps.pkg.applicationInfo?!=?null)?{?? ??????????????????systemApp?=?(ps.pkg.applicationInfo.flags?&?? ??????????????????????????ApplicationInfo.FLAG_SYSTEM)?!=?0;?? ??????????????}?? ??????????}?? ??????}?? ??????if?(systemApp?&&?onSd)?{?? ??????????//?Disable?updates?to?system?apps?on?sdcard?? ??????????Slog.w(TAG,?"Cannot?install?updates?to?system?apps?on?sdcard");?? ??????????res.returnCode?=?PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;?? ??????????return;?? ??????}?? ??????if?(!args.doRename(res.returnCode,?pkgName,?oldCodePath))?{?? ??????????res.returnCode?=?PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;?? ??????????return;?? ??????}?? ??????//?Set?application?objects?path?explicitly?after?the?rename?? ??????setApplicationInfoPaths(pkg,?args.getCodePath(),?args.getResourcePath());?? ??????pkg.applicationInfo.nativeLibraryDir?=?args.getNativeLibraryPath();?? ??????if?(replace)?{?? ??????????replacePackageLI(pkg,?parseFlags,?scanMode,?? ??????????????????installerPackageName,?res);?? ??????}?else?{?? ??????????installNewPackageLI(pkg,?parseFlags,?scanMode,?? ??????????????????installerPackageName,res);?? ??????}?? ??}?? ~~~ 最后判斷如果以前不存在那么調用installNewPackageLI() ~~~ private?void?installNewPackageLI(PackageParser.Package?pkg,?? ????????????int?parseFlags,int?scanMode,?? ????????????String?installerPackageName,?PackageInstalledInfo?res)?{?? ?????***********************省略若干*************************************************?? ????????PackageParser.Package?newPackage?=?scanPackageLI(pkg,?parseFlags,?scanMode,?? ???????????????System.currentTimeMillis());?? ?????***********************省略若干**************************************************???? }?? ~~~ 最后終于回到了和開機安裝一樣的地方.與開機方式安裝調用統一方法。 三、從ADB工具安裝? 其入口函數源文件為pm.java? (源文件路徑:android\frameworks\base\cmds\pm\src\com\android\commands\pm\pm.java) 其中\system\framework\pm.jar?包管理庫 包管理腳本?\system\bin\pm?解析 showUsage就是使用方法 ~~~ private static void showUsage() { System.err.println("usage: pm [list|path|install|uninstall]"); System.err.println(" pm list packages [-f]"); System.err.println(" pm list permission-groups"); System.err.println(" pm list permissions [-g] [-f] [-d] [-u] [GROUP]"); System.err.println(" pm list instrumentation [-f] [TARGET-PACKAGE]"); System.err.println(" pm list features"); System.err.println(" pm path PACKAGE"); System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH"); System.err.println(" pm uninstall [-k] PACKAGE"); System.err.println(" pm enable PACKAGE_OR_COMPONENT"); System.err.println(" pm disable PACKAGE_OR_COMPONENT"); System.err.println(" pm setInstallLocation [0/auto] [1/internal] [2/external]"); **********************省略************************** } ~~~ 安裝時候會調用?runInstall()方法 ~~~ private void runInstall() { int installFlags = 0; String installerPackageName = null; String opt; while ((opt=nextOption()) != null) { if (opt.equals("-l")) { installFlags |= PackageManager.INSTALL_FORWARD_LOCK; } else if (opt.equals("-r")) { installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; } else if (opt.equals("-i")) { installerPackageName = nextOptionData(); if (installerPackageName == null) { System.err.println("Error: no value specified for -i"); showUsage(); return; } } else if (opt.equals("-t")) { installFlags |= PackageManager.INSTALL_ALLOW_TEST; } else if (opt.equals("-s")) { // Override if -s option is specified. installFlags |= PackageManager.INSTALL_EXTERNAL; } else if (opt.equals("-f")) { // Override if -s option is specified. installFlags |= PackageManager.INSTALL_INTERNAL; } else { System.err.println("Error: Unknown option: " + opt); showUsage(); return; } } String apkFilePath = nextArg(); System.err.println("\tpkg: " + apkFilePath); if (apkFilePath == null) { System.err.println("Error: no package specified"); showUsage(); return; } PackageInstallObserver obs = new PackageInstallObserver(); try { mPm.installPackage(Uri.fromFile(new File(apkFilePath)), obs, installFlags, installerPackageName); synchronized (obs) { while (!obs.finished) { try { obs.wait(); } catch (InterruptedException e) { } } if (obs.result == PackageManager.INSTALL_SUCCEEDED) { System.out.println("Success"); } else { System.err.println("Failure [" + installFailureToString(obs.result) + "]"); } } } catch (RemoteException e) { System.err.println(e.toString()); System.err.println(PM_NOT_RUNNING_ERR); } } ~~~ 其中的??? ??? PackageInstallObserver?obs?=?new?PackageInstallObserver(); ???????? ????????????mPm.installPackage(Uri.fromFile(new?File(apkFilePath)),?obs,?installFlags, ????????????????????installerPackageName); 如果安裝成功 obs.result?==?PackageManager.INSTALL_SUCCEEDED) 又因為有 IPackageManage?mPm; ????????mPm?=?IpackageManager.Stub.asInterface(ServiceManager.getService("package")); Stub是接口IPackageManage的靜態抽象類,asInterface是返回IPackageManager代理的靜態方法。 因為class?PackageManagerService?extends?IPackageManager.Stub 所以mPm.installPackage?調用? ????/*?Called?when?a?downloaded?package?installation?has?been?confirmed?by?the?user?*/ ????public?void?installPackage( ????????????final?Uri?packageURI,?final?IPackageInstallObserver?observer,?final?int?flags,final?String?installerPackageName)? 這樣就是從網絡下載安裝的入口了。 四,從SD卡安裝 系統調用PackageInstallerActivity.java(/home/zhongda/androidSRC/vortex-8inch-for-hoperun/packages/apps/PackageInstaller/src/com/android/packageinstaller) 進入這個Activity會判斷信息是否有錯,然后調用 ??????private?void?initiateInstall()判斷是否曾經有過同名包的安裝,或者包已經安裝 通過后執行private?void?startInstallConfirm()?點擊OK按鈕后經過一系列的安裝信息的判斷Intent跳轉到 ~~~ public class InstallAppProgress extends Activity implements View.OnClickListener, OnCancelListener public void onCreate(Bundle icicle) { super.onCreate(icicle); Intent intent = getIntent(); mAppInfo = intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO); mPackageURI = intent.getData(); initView(); } ~~~ 方法中調用了initView()方法 ~~~ public void initView() { requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.op_progress); int installFlags = 0; PackageManager pm = getPackageManager(); try { PackageInfo pi = pm.getPackageInfo(mAppInfo.packageName, PackageManager.GET_UNINSTALLED_PACKAGES); if(pi != null) { installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; } } catch (NameNotFoundException e) { } if((installFlags & PackageManager.INSTALL_REPLACE_EXISTING )!= 0) { Log.w(TAG, "Replacing package:" + mAppInfo.packageName); } PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this, mAppInfo, mPackageURI); mLabel = as.label; PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet); mStatusTextView = (TextView)findViewById(R.id.center_text); mStatusTextView.setText(R.string.installing); mProgressBar = (ProgressBar) findViewById(R.id.progress_bar); mProgressBar.setIndeterminate(true); // Hide button till progress is being displayed mOkPanel = (View)findViewById(R.id.buttons_panel); mDoneButton = (Button)findViewById(R.id.done_button); mLaunchButton = (Button)findViewById(R.id.launch_button); mOkPanel.setVisibility(View.INVISIBLE); String installerPackageName = getIntent().getStringExtra( Intent.EXTRA_INSTALLER_PACKAGE_NAME); PackageInstallObserver observer = new PackageInstallObserver(); pm.installPackage(mPackageURI, observer, installFlags, installerPackageName); } ~~~ 方法最后我們可以看到再次調用安裝接口完成安裝。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看