INSTALL_FAILED_ABORTED

android 安装流程.报错
INSTALL_FAILED_ABORTED: Session was abandoned
网上查得到安装流程中 在安装最后会使用
getPackageManager().getPackageInstaller().abandonSession(mSessionId);
岂不知,这句话就是导致这个报错的元凶

正常流程中,不需要使用这句话.只有异常处理中才要用这句话

我们可以从源码中看一下:

client端
官方入口
frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java

/*** Send the package to the package installer and then register a event result observer that* will call {@link #launchFinishBasedOnResult(int, int, String)}*/private final class InstallingAsyncTask extends AsyncTask<Void, Void,PackageInstaller.Session> {volatile boolean isDone;@Overrideprotected PackageInstaller.Session doInBackground(Void... params) {PackageInstaller.Session session;try {session = getPackageManager().getPackageInstaller().openSession(mSessionId);} catch (IOException e) {synchronized (this) {isDone = true;notifyAll();}return null;}session.setStagingProgress(0);try {File file = new File(mPackageURI.getPath());try (InputStream in = new FileInputStream(file)) {long sizeBytes = file.length();try (OutputStream out = session.openWrite("PackageInstaller", 0, sizeBytes)) {byte[] buffer = new byte[1024 * 1024];while (true) {int numRead = in.read(buffer);if (numRead == -1) {session.fsync(out);break;}if (isCancelled()) {session.close();break;}out.write(buffer, 0, numRead);if (sizeBytes > 0) {float fraction = ((float) numRead / (float) sizeBytes);session.addProgress(fraction);}}}}return session;} catch (IOException | SecurityException e) {Log.e(LOG_TAG, "Could not write package", e);session.close();return null;} finally {synchronized (this) {isDone = true;notifyAll();}}}@Overrideprotected void onPostExecute(PackageInstaller.Session session) {if (session != null) {Intent broadcastIntent = new Intent(BROADCAST_ACTION);broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);broadcastIntent.setPackage(getPackageName());broadcastIntent.putExtra(EventResultPersister.EXTRA_ID, mInstallId);PendingIntent pendingIntent = PendingIntent.getBroadcast(InstallInstalling.this,mInstallId,broadcastIntent,PendingIntent.FLAG_UPDATE_CURRENT);session.commit(pendingIntent.getIntentSender());mCancelButton.setEnabled(false);setFinishOnTouchOutside(false);} else {getPackageManager().getPackageInstaller().abandonSession(mSessionId);if (!isCancelled()) {launchFailure(PackageManager.INSTALL_FAILED_INVALID_APK, null);}}}}

frameworks/base/core/java/android/content/pm/PackageInstaller.java

 /*** Completely abandon this session, destroying all staged data and* rendering it invalid. Abandoned sessions will be reported to* {@link SessionCallback} listeners as failures. This is equivalent to* opening the session and calling {@link Session#abandon()}.* 完全放弃此会话,破坏所有暂存的数据并使之无效。 放弃的会话将作为失败报告给{@link * SessionCallback}侦听器。 这等效于打开会话并调用{@link Session#abandon()}。*/public void abandon() {try {mSession.abandon();} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}

service端
真正执行的地方
frameworks/base/services/core/java/com/android/server/pm/PackageInstallerService.java
frameworks/base/services/core/java/com/android/server/pm/PackageInstallerSession.java

 @Overridepublic void abandon() {if (hasParentSessionId()) {throw new IllegalStateException("Session " + sessionId + " is a child of multi-package session "+ mParentSessionId +  " and may not be abandoned directly.");}List<PackageInstallerSession> childSessions = getChildSessionsNotLocked();synchronized (mLock) {if (params.isStaged && mDestroyed) {// If a user abandons staged session in an unsafe state, then system will try to// abandon the destroyed staged session when it is safe on behalf of the user.assertCallerIsOwnerOrRootOrSystemLocked();} else {assertCallerIsOwnerOrRootLocked();}if (isStagedAndInTerminalState()) {// We keep the session in the database if it's in a finalized state. It will be// removed by PackageInstallerService when the last update time is old enough.// Also, in such cases cleanStageDir() has already been executed so no need to// do it now.return;}if (mCommitted && params.isStaged) {mDestroyed = true;if (!mStagingManager.abortCommittedSessionLocked(this)) {// Do not clean up the staged session from system. It is not safe yet.mCallback.onStagedSessionChanged(this);return;}cleanStageDir(childSessions);}if (mRelinquished) {Slog.d(TAG, "Ignoring abandon after commit relinquished control");return;}destroyInternal();}dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部