tinker icon indicating copy to clipboard operation
tinker copied to clipboard

Android11+手机上TinkerDexOptimizer.performDexOptSecondaryByTransactionCode方法报错

Open chris-sharl opened this issue 3 years ago • 0 comments

异常类型:app运行时异常

手机型号:Mi 10 pro

手机系统版本:android 12

tinker版本:1.9.14.20

gradle版本:4.2.2

是否使用热更新SDK: 否

系统:Mac Os

堆栈/日志:

2022-05-25 11:08:56.958 16712-16743/? E/Tinker.ParallelDex: [-] Error.  java.lang.IllegalStateException: Cannot query transaction code of performDexOptSecondary.
        at com.tencent.tinker.loader.TinkerDexOptimizer.performDexOptSecondaryByTransactionCode(SourceFile:9)
        at com.tencent.tinker.loader.TinkerDexOptimizer.triggerPMDexOptOnDemand(SourceFile:19)
        at com.tencent.tinker.loader.TinkerDexOptimizer.access$200(SourceFile:1)
        at com.tencent.tinker.loader.TinkerDexOptimizer$OptimizeWorker.run(SourceFile:18)
        at com.tencent.tinker.loader.TinkerDexOptimizer.optimizeAll(SourceFile:7)
        at com.tencent.tinker.loader.TinkerDexOptimizer.optimizeAll(SourceFile:2)
        at com.tencent.tinker.lib.patch.DexDiffPatchInternal.dexOptimizeDexFiles(SourceFile:13)
        at com.tencent.tinker.lib.patch.DexDiffPatchInternal.patchDexExtractViaDexDiff(SourceFile:16)
        at com.tencent.tinker.lib.patch.DexDiffPatchInternal.tryRecoverDexFiles(SourceFile:6)
        at com.tencent.tinker.lib.patch.UpgradePatch.tryPatch(SourceFile:44)
        at com.tencent.tinker.lib.service.TinkerPatchService.doApplyPatch(SourceFile:15)
        at com.tencent.tinker.lib.service.TinkerPatchService.onHandleIntent(SourceFile:2)
        at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:78)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loopOnce(Looper.java:210)
        at android.os.Looper.loop(Looper.java:299)
        at android.os.HandlerThread.run(HandlerThread.java:67)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at com.tencent.tinker.loader.TinkerDexOptimizer.performDexOptSecondaryByTransactionCode(SourceFile:6)
        at com.tencent.tinker.loader.TinkerDexOptimizer.triggerPMDexOptOnDemand(SourceFile:19) 
        at com.tencent.tinker.loader.TinkerDexOptimizer.access$200(SourceFile:1) 
        at com.tencent.tinker.loader.TinkerDexOptimizer$OptimizeWorker.run(SourceFile:18) 
        at com.tencent.tinker.loader.TinkerDexOptimizer.optimizeAll(SourceFile:7) 
        at com.tencent.tinker.loader.TinkerDexOptimizer.optimizeAll(SourceFile:2) 
        at com.tencent.tinker.lib.patch.DexDiffPatchInternal.dexOptimizeDexFiles(SourceFile:13) 
        at com.tencent.tinker.lib.patch.DexDiffPatchInternal.patchDexExtractViaDexDiff(SourceFile:16) 
        at com.tencent.tinker.lib.patch.DexDiffPatchInternal.tryRecoverDexFiles(SourceFile:6) 
        at com.tencent.tinker.lib.patch.UpgradePatch.tryPatch(SourceFile:44) 
        at com.tencent.tinker.lib.service.TinkerPatchService.doApplyPatch(SourceFile:15) 
        at com.tencent.tinker.lib.service.TinkerPatchService.onHandleIntent(SourceFile:2) 
        at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:78) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loopOnce(Looper.java:210) 
        at android.os.Looper.loop(Looper.java:299) 
        at android.os.HandlerThread.run(HandlerThread.java:67) 
     Caused by: java.lang.NoSuchFieldException: No field TRANSACTION_performDexOptSecondary in class Landroid/content/pm/IPackageManager$Stub; (declaration of 'android.content.pm.IPackageManager$Stub' appears in /system/framework/framework.jar)
        at java.lang.Class.getDeclaredField(Native Method)
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.tencent.tinker.loader.TinkerDexOptimizer.performDexOptSecondaryByTransactionCode(SourceFile:6) 
        at com.tencent.tinker.loader.TinkerDexOptimizer.triggerPMDexOptOnDemand(SourceFile:19) 
        at com.tencent.tinker.loader.TinkerDexOptimizer.access$200(SourceFile:1) 
        at com.tencent.tinker.loader.TinkerDexOptimizer$OptimizeWorker.run(SourceFile:18) 
        at com.tencent.tinker.loader.TinkerDexOptimizer.optimizeAll(SourceFile:7) 
        at com.tencent.tinker.loader.TinkerDexOptimizer.optimizeAll(SourceFile:2) 
        at com.tencent.tinker.lib.patch.DexDiffPatchInternal.dexOptimizeDexFiles(SourceFile:13) 
        at com.tencent.tinker.lib.patch.DexDiffPatchInternal.patchDexExtractViaDexDiff(SourceFile:16) 
        at com.tencent.tinker.lib.patch.DexDiffPatchInternal.tryRecoverDexFiles(SourceFile:6) 
        at com.tencent.tinker.lib.patch.UpgradePatch.tryPatch(SourceFile:44) 
        at com.tencent.tinker.lib.service.TinkerPatchService.doApplyPatch(SourceFile:15) 
        at com.tencent.tinker.lib.service.TinkerPatchService.onHandleIntent(SourceFile:2) 
        at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:78) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loopOnce(Looper.java:210) 
        at android.os.Looper.loop(Looper.java:299) 
        at android.os.HandlerThread.run(HandlerThread.java:67) 

分析: TinkerDexOptimizer.performDexOptSecondaryByTransactionCode方法内有如下代码片段:

              try {
                    final Method getDeclaredFieldMethod = ShareReflectUtil.findMethod(
                            Class.class, "getDeclaredField", String.class);
                    getDeclaredFieldMethod.setAccessible(true);
                    final Field cstField = (Field) getDeclaredFieldMethod.invoke(
                            Class.forName("android.content.pm.IPackageManager$Stub"),
                            "TRANSACTION_performDexOptSecondary"
                    );
                    cstField.setAccessible(true);
                    sPerformDexOptSecondaryTransactionCode[0] = (int) cstField.get(null);
                } catch (Throwable thr) {
                    throw new IllegalStateException("Cannot query transaction code of performDexOptSecondary.", thr);
                }

将这部分代码摘出来进行测试: android9设备上能正常获取. android11和android12设备上会报NoSuchFieldException。

将代码改成以下代码再次进行测试:

            try {
                final Method getDeclaredFieldMethod = ShareReflectUtil.findMethod(
                        Class.class, "getDeclaredFields");
                getDeclaredFieldMethod.setAccessible(true);
                Field[] fields = (Field[]) getDeclaredFieldMethod.invoke(
                        Class.forName("android.content.pm.IPackageManager$Stub"));
                for (Field field : fields) {
                    field.setAccessible(true);
                    LogUtils.e("tinker", "field: " + field.getName());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

android9设备可以获取如下值:

#onClick : field: DESCRIPTOR
#onClick : field: TRANSACTION_activitySupportsIntent
#onClick : field: TRANSACTION_addCrossProfileIntentFilter
#onClick : field: TRANSACTION_addOnPermissionsChangeListener
#onClick : field: TRANSACTION_addPermission
#onClick : field: TRANSACTION_addPermissionAsync
#onClick : field: TRANSACTION_addPersistentPreferredActivity
#onClick : field: TRANSACTION_addPreferredActivity
#onClick : field: TRANSACTION_canForwardTo
#onClick : field: TRANSACTION_canRequestPackageInstalls
#onClick : field: TRANSACTION_canonicalToCurrentPackageNames
#onClick : field: TRANSACTION_checkPackageStartable
#onClick : field: TRANSACTION_checkPermission
#onClick : field: TRANSACTION_checkSignatures
#onClick : field: TRANSACTION_checkUidPermission
#onClick : field: TRANSACTION_checkUidSignatures
#onClick : field: TRANSACTION_clearApplicationProfileData
#onClick : field: TRANSACTION_clearApplicationUserData
#onClick : field: TRANSACTION_clearCrossProfileIntentFilters
#onClick : field: TRANSACTION_clearPackagePersistentPreferredActivities
#onClick : field: TRANSACTION_clearPackagePreferredActivities
#onClick : field: TRANSACTION_currentToCanonicalPackageNames
#onClick : field: TRANSACTION_deleteApplicationCacheFiles
#onClick : field: TRANSACTION_deleteApplicationCacheFilesAsUser
#onClick : field: TRANSACTION_deletePackageAsUser
#onClick : field: TRANSACTION_deletePackageVersioned
#onClick : field: TRANSACTION_deletePreloadsFileCache
#onClick : field: TRANSACTION_dumpProfiles
#onClick : field: TRANSACTION_enterSafeMode
#onClick : field: TRANSACTION_extendVerificationTimeout
#onClick : field: TRANSACTION_findPersistentPreferredActivity
#onClick : field: TRANSACTION_finishPackageInstall
#onClick : field: TRANSACTION_flushPackageRestrictionsAsUser
#onClick : field: TRANSACTION_forceDexOpt
#onClick : field: TRANSACTION_freeStorage
#onClick : field: TRANSACTION_freeStorageAndNotify
#onClick : field: TRANSACTION_getActivityInfo
#onClick : field: TRANSACTION_getAllIntentFilters
#onClick : field: TRANSACTION_getAllPackages
#onClick : field: TRANSACTION_getAllPermissionGroups
#onClick : field: TRANSACTION_getAppOpPermissionPackages
#onClick : field: TRANSACTION_getApplicationEnabledSetting
#onClick : field: TRANSACTION_getApplicationHiddenSettingAsUser
#onClick : field: TRANSACTION_getApplicationInfo
#onClick : field: TRANSACTION_getArtManager
#onClick : field: TRANSACTION_getBlockUninstallForUser
#onClick : field: TRANSACTION_getChangedPackages
#onClick : field: TRANSACTION_getComponentEnabledSetting
#onClick : field: TRANSACTION_getDefaultAppsBackup
#onClick : field: TRANSACTION_getDefaultBrowserPackageName
#onClick : field: TRANSACTION_getFlagsForUid
#onClick : field: TRANSACTION_getHarmfulAppWarning
#onClick : field: TRANSACTION_getHomeActivities
#onClick : field: TRANSACTION_getInstallLocation
#onClick : field: TRANSACTION_getInstallReason
#onClick : field: TRANSACTION_getInstalledApplications
#onClick : field: TRANSACTION_getInstalledPackages
#onClick : field: TRANSACTION_getInstallerPackageName
#onClick : field: TRANSACTION_getInstantAppAndroidId
#onClick : field: TRANSACTION_getInstantAppCookie
#onClick : field: TRANSACTION_getInstantAppIcon
#onClick : field: TRANSACTION_getInstantAppInstallerComponent
#onClick : field: TRANSACTION_getInstantAppResolverComponent
#onClick : field: TRANSACTION_getInstantAppResolverSettingsComponent
#onClick : field: TRANSACTION_getInstantApps
#onClick : field: TRANSACTION_getInstrumentationInfo
#onClick : field: TRANSACTION_getIntentFilterVerificationBackup
#onClick : field: TRANSACTION_getIntentFilterVerifications
#onClick : field: TRANSACTION_getIntentVerificationStatus
#onClick : field: TRANSACTION_getKeySetByAlias
#onClick : field: TRANSACTION_getLastChosenActivity
#onClick : field: TRANSACTION_getMoveStatus
#onClick : field: TRANSACTION_getNameForUid
#onClick : field: TRANSACTION_getNamesForUids
#onClick : field: TRANSACTION_getPackageGids
#onClick : field: TRANSACTION_getPackageInfo
#onClick : field: TRANSACTION_getPackageInfoVersioned
#onClick : field: TRANSACTION_getPackageInstaller
#onClick : field: TRANSACTION_getPackageSizeInfo
#onClick : field: TRANSACTION_getPackageUid
#onClick : field: TRANSACTION_getPackagesForUid
#onClick : field: TRANSACTION_getPackagesHoldingPermissions
#onClick : field: TRANSACTION_getPermissionControllerPackageName
#onClick : field: TRANSACTION_getPermissionFlags
#onClick : field: TRANSACTION_getPermissionGrantBackup
#onClick : field: TRANSACTION_getPermissionGroupInfo
#onClick : field: TRANSACTION_getPermissionInfo
#onClick : field: TRANSACTION_getPersistentApplications
#onClick : field: TRANSACTION_getPreferredActivities
#onClick : field: TRANSACTION_getPreferredActivityBackup
#onClick : field: TRANSACTION_getPrivateFlagsForUid
#onClick : field: TRANSACTION_getProviderInfo
#onClick : field: TRANSACTION_getReceiverInfo
#onClick : field: TRANSACTION_getServiceInfo
#onClick : field: TRANSACTION_getServicesSystemSharedLibraryPackageName
#onClick : field: TRANSACTION_getSharedLibraries
#onClick : field: TRANSACTION_getSharedSystemSharedLibraryPackageName
#onClick : field: TRANSACTION_getSigningKeySet
#onClick : field: TRANSACTION_getSuspendedPackageAppExtras
#onClick : field: TRANSACTION_getSystemAvailableFeatures
#onClick : field: TRANSACTION_getSystemSharedLibraryNames
#onClick : field: TRANSACTION_getSystemTextClassifierPackageName
#onClick : field: TRANSACTION_getUidForSharedUser
#onClick : field: TRANSACTION_getVerifierDeviceIdentity
#onClick : field: TRANSACTION_grantDefaultPermissionsToActiveLuiApp
#onClick : field: TRANSACTION_grantDefaultPermissionsToEnabledCarrierApps
#onClick : field: TRANSACTION_grantDefaultPermissionsToEnabledImsServices
#onClick : field: TRANSACTION_grantDefaultPermissionsToEnabledTelephonyDataServices
#onClick : field: TRANSACTION_grantRuntimePermission
#onClick : field: TRANSACTION_hasSigningCertificate
#onClick : field: TRANSACTION_hasSystemFeature
#onClick : field: TRANSACTION_hasSystemUidErrors
#onClick : field: TRANSACTION_hasUidSigningCertificate
#onClick : field: TRANSACTION_installExistingPackageAsUser
#onClick : field: TRANSACTION_isFirstBoot
#onClick : field: TRANSACTION_isInstantApp
#onClick : field: TRANSACTION_isOnlyCoreApps
#onClick : field: TRANSACTION_isPackageAvailable
#onClick : field: TRANSACTION_isPackageDeviceAdminOnAnyUser
#onClick : field: TRANSACTION_isPackageSignedByKeySet
#onClick : field: TRANSACTION_isPackageSignedByKeySetExactly
#onClick : field: TRANSACTION_isPackageStateProtected
#onClick : field: TRANSACTION_isPackageSuspendedForUser
#onClick : field: TRANSACTION_isPermissionEnforced
#onClick : field: TRANSACTION_isPermissionRevokedByPolicy
#onClick : field: TRANSACTION_isProtectedBroadcast
#onClick : field: TRANSACTION_isSafeMode
#onClick : field: TRANSACTION_isStorageLow
#onClick : field: TRANSACTION_isUidPrivileged
#onClick : field: TRANSACTION_isUpgrade
#onClick : field: TRANSACTION_logAppProcessStartIfNeeded
#onClick : field: TRANSACTION_movePackage
#onClick : field: TRANSACTION_movePrimaryStorage
#onClick : field: TRANSACTION_nextPackageToClean
#onClick : field: TRANSACTION_notifyDexLoad
#onClick : field: TRANSACTION_notifyPackageUse
#onClick : field: TRANSACTION_performDexOptMode
#onClick : field: TRANSACTION_performDexOptSecondary
#onClick : field: TRANSACTION_performFstrimIfNeeded
#onClick : field: TRANSACTION_queryContentProviders
#onClick : field: TRANSACTION_queryInstrumentation
#onClick : field: TRANSACTION_queryIntentActivities
#onClick : field: TRANSACTION_queryIntentActivityOptions
#onClick : field: TRANSACTION_queryIntentContentProviders
#onClick : field: TRANSACTION_queryIntentReceivers
#onClick : field: TRANSACTION_queryIntentServices
#onClick : field: TRANSACTION_queryPermissionsByGroup
#onClick : field: TRANSACTION_querySyncProviders
#onClick : field: TRANSACTION_reconcileSecondaryDexFiles
#onClick : field: TRANSACTION_registerDexModule
#onClick : field: TRANSACTION_registerMoveCallback
#onClick : field: TRANSACTION_removeOnPermissionsChangeListener
#onClick : field: TRANSACTION_removePermission
#onClick : field: TRANSACTION_replacePreferredActivity
#onClick : field: TRANSACTION_resetApplicationPreferences
#onClick : field: TRANSACTION_resetRuntimePermissions
#onClick : field: TRANSACTION_resolveContentProvider
#onClick : field: TRANSACTION_resolveIntent
#onClick : field: TRANSACTION_resolveService
#onClick : field: TRANSACTION_restoreDefaultApps
#onClick : field: TRANSACTION_restoreIntentFilterVerification
#onClick : field: TRANSACTION_restorePermissionGrants
#onClick : field: TRANSACTION_restorePreferredActivities
#onClick : field: TRANSACTION_revokeDefaultPermissionsFromDisabledTelephonyDataServices
#onClick : field: TRANSACTION_revokeDefaultPermissionsFromLuiApps
#onClick : field: TRANSACTION_revokeRuntimePermission
#onClick : field: TRANSACTION_revokeRuntimePermissionNotKill
#onClick : field: TRANSACTION_runBackgroundDexoptJob
#onClick : field: TRANSACTION_setApplicationCategoryHint
#onClick : field: TRANSACTION_setApplicationEnabledSetting
#onClick : field: TRANSACTION_setApplicationHiddenSettingAsUser
#onClick : field: TRANSACTION_setBlockUninstallForUser
#onClick : field: TRANSACTION_setComponentEnabledSetting
#onClick : field: TRANSACTION_setDefaultBrowserPackageName
#onClick : field: TRANSACTION_setHarmfulAppWarning
#onClick : field: TRANSACTION_setHomeActivity
#onClick : field: TRANSACTION_setInstallLocation
#onClick : field: TRANSACTION_setInstallerPackageName
#onClick : field: TRANSACTION_setInstantAppCookie
#onClick : field: TRANSACTION_setLastChosenActivity
#onClick : field: TRANSACTION_setPackageStoppedState
#onClick : field: TRANSACTION_setPackagesSuspendedAsUser
#onClick : field: TRANSACTION_setPermissionEnforced
#onClick : field: TRANSACTION_setRequiredForSystemUser
#onClick : field: TRANSACTION_setSystemAppHiddenUntilInstalled
#onClick : field: TRANSACTION_setSystemAppInstallState
#onClick : field: TRANSACTION_setUpdateAvailable
#onClick : field: TRANSACTION_shouldShowRequestPermissionRationale
#onClick : field: TRANSACTION_systemReady
#onClick : field: TRANSACTION_unregisterMoveCallback
#onClick : field: TRANSACTION_updateIntentVerificationStatus
#onClick : field: TRANSACTION_updatePackagesIfNeeded
#onClick : field: TRANSACTION_updatePermissionFlags
#onClick : field: TRANSACTION_updatePermissionFlagsForAllApps
#onClick : field: TRANSACTION_verifyIntentFilter
#onClick : field: TRANSACTION_verifyPendingInstall

而在android12设备上,仅获取到以下值

#onClick : field: TRANSACTION_getApplicationInfo

个人结论:android11+对于反射增加了限制,影响了这部分代码的有效性。

个人建议:网络上有一些开源方案,可以绕过android 11对于反射的限制,经测试是好使的。可以尝试引入进来,或者调整dex优化的实现方案。

chris-sharl avatar May 25 '22 03:05 chris-sharl