APK安装原理

一 SD卡安装apk详解

   首先调用PackageInstallerActivity

//get intent information
        final Intent intent = getIntent();
        mPackageURI = intent.getData();
        mPm = getPackageManager();
        mPkgInfo = PackageUtil.getPackageInfo(mPackageURI);
        //解析错误当解析清单。中止安装,检查解析错误
        // Check for parse errors
        if(mPkgInfo == null) {
            Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation");
            showDialogInner(DLG_PACKAGE_ERROR);
            setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
            return;
        }
        
        //set view
        setContentView(R.layout.install_start);
        mInstallConfirm = findViewById(R.id.install_confirm_panel);
        mInstallConfirm.setVisibility(View.INVISIBLE);
        PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this,
                mPkgInfo.applicationInfo, mPackageURI);
        PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
        //处理安装源
        // Deal with install source.
        String callerPackage = getCallingPackage();
        if (callerPackage != null && intent.getBooleanExtra(
                Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)) {
            try {
                mSourceInfo = mPm.getApplicationInfo(callerPackage, 0);
                if (mSourceInfo != null) {
                    if ((mSourceInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
                        // System apps don't need to be approved.
                        initiateInstall();
                        return;
                    }
                    /* for now this is disabled, since the user would need to
                     * have enabled the global "unknown sources" setting in the
                     * first place in order to get here.
                    SharedPreferences prefs = getSharedPreferences(PREFS_ALLOWED_SOURCES,
                            Context.MODE_PRIVATE);
                    if (prefs.getBoolean(mSourceInfo.packageName, false)) {
                        // User has already allowed this one.
                        initiateInstall();
                        return;
                    }
                    //ask user to enable setting first
                    showDialogInner(DLG_ALLOW_SOURCE);
                    return;
                     */
                }
            } catch (NameNotFoundException e) {
            }
        }
        //0 只允许安装在Android市场 ,1 允许安装来自其他来源
         //是否应该允许安装包安装器的应用下载安卓市场以外的其他来源
        // Check unknown sources.
        if (!isInstallingUnknownAppsAllowed()) {
            //ask user to enable setting first
            showDialogInner(DLG_UNKNOWN_APPS);
            return;
        }
        initiateInstall();
/**
     * 判断是否曾经有过同名包的安装
     */
    
    private void initiateInstall() {
        String pkgName = mPkgInfo.packageName;
        // Check if there is already a package on the device with this name
        // but it has been renamed to something else.
        String[] oldName = mPm.canonicalToCurrentPackageNames(new String[] { pkgName });
        if (oldName != null && oldName.length > 0 && oldName[0] != null) {
            pkgName = oldName[0];
            mPkgInfo.setPackageName(pkgName);
        }
        //
        // Check if package is already installed. display confirmation dialog if replacing pkg
        try {
            mAppInfo = mPm.getApplicationInfo(pkgName,
                    PackageManager.GET_UNINSTALLED_PACKAGES);
        } catch (NameNotFoundException e) {
            mAppInfo = null;
        }
        //检查是否已经安装。如果显示确认对话框如果更换包裹
        if (mAppInfo == null || getIntent().getBooleanExtra(Intent.EXTRA_ALLOW_REPLACE, false)) {
            startInstallConfirm();
        } else {
            if(localLOGV) Log.i(TAG, "Replacing existing package:"+
                    mPkgInfo.applicationInfo.packageName);
            showDialogInner(DLG_REPLACE_APP);
        }
    }

 

/**
	 * 确认是否需要安装
	 */
    private void startInstallConfirm() {
        LinearLayout permsSection = (LinearLayout) mInstallConfirm.findViewById(R.id.permissions_section);
        LinearLayout securityList = (LinearLayout) permsSection.findViewById(
                R.id.security_settings_list);
        boolean permVisible = false;
        if(mPkgInfo != null) {
            AppSecurityPermissions asp = new AppSecurityPermissions(this, mPkgInfo);
            if(asp.getPermissionCount() > 0) {
                permVisible = true;
                securityList.addView(asp.getPermissionsView());
            }
        }
        if(!permVisible){
            permsSection.setVisibility(View.INVISIBLE);
        }
        mInstallConfirm.setVisibility(View.VISIBLE);
        mOk = (Button)findViewById(R.id.ok_button);
        mCancel = (Button)findViewById(R.id.cancel_button);
        mOk.setOnClickListener(this);
        mCancel.setOnClickListener(this);
    }
/**
     * 点击OK按钮后经过一系列的安装信息的判断Intent跳转到
     * 开始InstallAppProgress实际安装应用程序
     */
    public void onClick(View v) {
        if(v == mOk) {
            // Start subactivity to actually install the application
            Intent newIntent = new Intent();
            newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO,
                    mPkgInfo.applicationInfo);
            //appURI传递过去
            newIntent.setData(mPackageURI);
            newIntent.setClass(this, InstallAppProgress.class);
            //安装的包名字
            String installerPackageName = getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME);
            if (installerPackageName != null) {
                newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, installerPackageName);
            }
            if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
                newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
                newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
            }
            if(localLOGV) Log.i(TAG, "downloaded app uri="+mPackageURI);
            startActivity(newIntent);
            finish();
        } else if(v == mCancel) {
            // Cancel and finish
            setResult(RESULT_CANCELED);
            finish();
        }
    }

调用这个类进行安装InstallAppProgress

public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        Intent intent = getIntent();
        mAppInfo = intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
        mPackageURI = intent.getData();
        initView();
    }
 
 
public void initView() {
        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);
        mExplanationTextView = (TextView) findViewById(R.id.center_explanation);
        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);
    }

你可能感兴趣的:(APK安装原理)