1

我正在开发的应用程序不在 Play 商店中,它直接安装在用于特定项目的设备上。我们确实使用内部密钥库对应用程序进行签名。使用我们自己的网络服务将更新发送到设备,这些服务会下载更新的 APK 并提示用户安装更新,如下所示。

Uri packageURI = Uri.parse("package:" + this.getPackageName());

Intent intent = new Intent(android.content.Intent.ACTION_VIEW, packageURI);

intent.setDataAndType(Uri.fromFile(new File(downloadPath + "/" + package_name)),
"application/vnd.android.package-archive");

this.startActivity(intent);

当我们开始使用 gradle 构建变体以允许轻松交换资产时,它的设置不正确,如下所示:

productFlavors {
    SampleProject {
        dimension "project"
        applicationId "companyID.SampleProject"
        versionCode = "2"
        versionName = "3.0.20180514.0"
        resValue "string", "app_name", "Sample Project"
    }
}

请注意版本代码和名称的错误分配以及版本代码是字符串的事实。

这实际上是按原样工作的,直到我们得到大于 9(两位数)的版本代码。这导致了下面的(预期的)错误。

无法将具有类“java.lang.String”的对象“10”转换为类“java.lang.Integer”

这导致解决以下项目的问题。

productFlavors {
    SampleProject {
        dimension "project"
        applicationId "companyID.SampleProject"
        versionCode 2
        versionName "3.0.20180514.0"
        resValue "string", "app_name", "Sample Project"
    }
}

这按预期工作,并让我们超越版本代码 10。

问题是此更改不允许在使用旧的错误方法构建的应用程序的先前版本上安装更新。这样做时,安装几乎立即失败,并简单地显示“未安装应用程序”。

我已经测试确保没有其他任何改变,使用相同的密钥库和资产仍然失败。我们一直在使用的修复方法是将版本代码保留为“9”并增加版本名称,但这并不理想。

任何建议,将不胜感激。这些项目的生命周期往往有限,更新不多,所以这不是一个主要问题,但为现有项目修复它会很好,这样我们就可以继续增加两者。

编辑 这是尝试使用更正的构建变体安装签名 APK 时 Logcat 中的错误。

05-14 12:00:51.785 3958-5291/? E/Parcel: Class not found when unmarshalling: com.android.packageinstaller.InstallFlowAnalytics
java.lang.ClassNotFoundException: com.android.packageinstaller.InstallFlowAnalytics
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:324)
    at android.os.Parcel.readParcelableCreator(Parcel.java:2404)
    at android.os.Parcel.readParcelable(Parcel.java:2358)
    at android.os.Parcel.readValue(Parcel.java:2264)
    at android.os.Parcel.readArrayMapInternal(Parcel.java:2614)
    at android.os.BaseBundle.unparcel(BaseBundle.java:221)
    at android.os.BaseBundle.getString(BaseBundle.java:920)
    at android.content.Intent.getStringExtra(Intent.java:6200)
    at com.android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.java:2752)
    at com.android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.java:2209)
    at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:6401)
    at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:6173)
    at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:170)
    at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:4028)
    at android.os.Binder.execTransact(Binder.java:453)
 Caused by: java.lang.ClassNotFoundException: com.android.packageinstaller.InstallFlowAnalytics
    at java.lang.Class.classForName(Native Method)
    at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
    at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
    at java.lang.Class.classForName(Native Method) 
    at java.lang.Class.forName(Class.java:324) 
    at android.os.Parcel.readParcelableCreator(Parcel.java:2404) 
    at android.os.Parcel.readParcelable(Parcel.java:2358) 
    at android.os.Parcel.readValue(Parcel.java:2264) 
    at android.os.Parcel.readArrayMapInternal(Parcel.java:2614) 
    at android.os.BaseBundle.unparcel(BaseBundle.java:221) 
    at android.os.BaseBundle.getString(BaseBundle.java:920) 
    at android.content.Intent.getStringExtra(Intent.java:6200) 
    at com.android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.java:2752) 
    at com.android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.java:2209) 
    at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:6401) 
    at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:6173) 
    at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:170) 
    at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:4028) 
    at android.os.Binder.execTransact(Binder.java:453) 
 Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

根据对该错误的研究,我尝试安装的先前版本是几天前使用 Android Studio 构建的,中间没有重大更改或更新,并且仅使用 V1 签名,就像之前的构建一样。改回不正确的方式,将代码设置为 9 并仅增加版本名称允许正确安装更新。

4

1 回答 1

0

这就是我认为正在发生的事情。

如果我们有一个测试类:

public class MyClass {
    public static void main(String args[]) {
int anInt = '1';
        System.out.println("anInt  is = " + anInt);
    }
}
It runs with result `anInt  is = 49`

将“1”更改为“9”

It runs with result `anInt  is = 57`

将“9”更改为“10”

It fails (like your cast error): 

/MyClass.java:3: error: incompatible types: String cannot be converted to int
int anInt = "10";
            ^
1 error

因此,如果您使用58错误修复代码,它 应该可以工作。versionCode

这是一个snippet,因此您可以自己尝试javascript

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html><head><script>
    $(function() {
      var anInt = ('1').charCodeAt(0);
      console.info("anInt is = " + anInt);
    });
  </script></head><body>
  function();
</body></html>

于 2018-05-14T17:03:50.030 回答