[英]Android 5.x ClassNotFoundException works fine on 6.0+
I have updated my project's minSdkVersion from 19 to 21. This has caused an issue on 5.0/5.1 devices where I can't run the app. 我已将项目的minSdkVersion从19更新为21.这导致5.0 / 5.1设备上的问题,我无法运行该应用程序。 I keep getting a ClassNotFoundException on my Application class.
我一直在我的Application类上得到一个ClassNotFoundException。 The full log, Application class, and gradle file are below.
完整日志,应用程序类和gradle文件如下所示。 If I revert my project back to minSdkVersion 19 then the app will run on 4.4+ with no problems.
如果我将我的项目还原为minSdkVersion 19,那么应用程序将在4.4+上运行,没有任何问题。
What I have tried 我试过了什么
Cleaning/Rebuilding 清洗/重建
Updating and downgrading the build tools version 更新和降级构建工具版本
All support library's across projects have same version number 跨项目的所有支持库都具有相同的版本号
Making all my manifest classes relative and then absolute 使我所有的清单类相对而绝对
Updated all Sdk and build tools 更新了所有Sdk和构建工具
Log 日志
04-27 14:37:07.152 6278-6278/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.package.testapp, PID: 6278
java.lang.RuntimeException: Unable to instantiate application com.package.TestApplication: java.lang.ClassNotFoundException: Didn't find class "com.package.Application" on path: DexPathList[[zip file "/data/app/com.package.testapp-1/base.apk"],nativeLibraryDirectories=[/data/app/com.package.testapp-1/lib/x86_64, /vendor/lib64, /system/lib64]]
at android.app.LoadedApk.makeApplication(LoadedApk.java:563)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4526)
at android.app.ActivityThread.access$1500(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.package.TestApplication" on path: DexPathList[[zip file "/data/app/com.package.testapp-1/base.apk"],nativeLibraryDirectories=[/data/app/com.package.testapp-1/lib/x86_64, /vendor/lib64, /system/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at android.app.Instrumentation.newApplication(Instrumentation.java:980)
at android.app.LoadedApk.makeApplication(LoadedApk.java:558)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4526)
at android.app.ActivityThread.access$1500(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Suppressed: java.lang.ClassNotFoundException: com.package.testapp.welcome.TestClaimApplication
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:504)
... 13 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
Gradle 摇篮
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'io.fabric.tools:gradle:1.+'
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
repositories {
maven { url 'https://maven.fabric.io/public' }
}
android {
compileSdkVersion 25
buildToolsVersion '25.0.3'
defaultConfig {
applicationId "com.package.testapp"
minSdkVersion 21
multiDexEnabled = true
targetSdkVersion 25
versionCode 2
versionName "0.7"
renderscriptTargetApi 18 // support mode not supported 21+
renderscriptSupportModeEnabled true
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
dexOptions {
javaMaxHeapSize "4g"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
productFlavors {
companylocal
companymaven
}
}
dependencies {
def ext = rootProject.ext;
compile fileTree(include: ['*.jar'], dir: 'libs')
compile "com.android.support:appcompat-v7:${ext.supportLibraryVersion}"
compile "com.android.support:design:${ext.supportLibraryVersion}"
compile 'com.romandanylyk:pageindicatorview:0.0.9'
compile "com.jakewharton:butterknife:${ext.butterknifeLibraryVersion}"
annotationProcessor "com.jakewharton:butterknife-compiler:${ext.butterknifeLibraryVersion}"
compile "uk.co.chrisjenx:calligraphy:2.2.0"
compile 'com.android.support:multidex:1.0.1'
// Crashlytics Kit - for crash handling
compile('com.crashlytics.sdk.android:crashlytics:2.5.2@aar') {
transitive = true
}
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.0'
testCompile "com.squareup.okhttp3:mockwebserver:${ext.okHttp3LibraryVersion}"
testCompile('com.squareup.assertj:assertj-android:1.1.1') {
exclude module: 'support-annotations'
}
}
Application 应用
public class TestApplication extends Application {
Engine engine;
@Override
public void onCreate() {
super.onCreate();
String privateServerUrlLocal = getString(R.string.server_url);
ProfileLauncher profileLauncher = getProfileLauncher();
LoginLauncher loginLauncher = getLoginLauncher();
// Set up Crash Analytics
final CrashlyticsCore crashlyticsCore = new CrashlyticsCore.Builder().disabled(DEBUG).build();
Fabric.with(this, new Crashlytics.Builder().core(crashlyticsCore).build());
Intent intent = new Intent(this, LogoutService.class);
startService(intent);
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("")
.add("")
.build();
engine = new Engine.Builder(privateServerUrlLocal, getString(R.string.other_server_url))
.setCertificatePinner(certificatePinner)
.setSDKPartnerSetupManager(getSdkPartnerManager())
.setLogoutActionHandler(getLogoutActionHandler())
.setVLocationManager(new VLocationManagerImp())
.setDebug(DEBUG)
.addDeepLinkHandler(new ClaimDeepLinkHandler(loginLauncher, profileLauncher))
.addDeepLinkHandler(new LinkGiftCodeDeeplinkHandler(loginLauncher, profileLauncher))
.addDeepLinkHandler(new OpenLinkDeepLinkHandler())
.addDeepLinkHandler(new DetailsDeepLinkHandler())
.addClaimConfig(new ClaimConfig(false, false, false, false, true))
.build();
engine.startup(this);
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(base);
}
}
Manifest 表现
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.package.testapp">
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.flash"
android:required="false" />
<!-- Required for g+ login -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:name=".TestApplication"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<service
android:name="com.package.companycommon.ui.LogoutService"
android:stopWithTask="true" />
<activity
android:name=".LaunchActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".welcome.WelcomeActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus" />
<activity
android:name=".RegisterActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".LoginActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ActivationActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".AddPhoneNumberActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ForgotPasswordActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".GiftHistoryActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus" />
<activity
android:name="com.package.PartnerLoginHiddenActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus" />
<activity
android:name=".tutorial.TutorialActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus" />
<activity
android:name=".CreateNewPasswordActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus" />
<activity
android:name=".settings.SettingsActivity"
android:screenOrientation="portrait">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".GiftHistoryActivity" />
</activity>
<activity
android:name=".settings.ExtraSettingsActivity"
android:label="@string/settings"
android:screenOrientation="portrait">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".settings.SettingsActivity" />
</activity>
<activity
android:name="companyapp.company.NewsActivity"
android:label="@string/notifications"
android:screenOrientation="portrait"
android:theme="@style/AppTheme" />
<activity
android:name=".termsandconditions.CompanyTermsAndConditionsActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme" />
<activity
android:name="com.package.companycommon.ui.PhotoViewerActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme" />
<activity
android:name="com.package.company.details.CompanyDetailActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme" />
<activity
android:name="com.package.company.details.CompanyDetailActivityLocation"
android:screenOrientation="portrait"
android:theme="@style/AppTheme">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.package.company.details.CompanyDetailActivity" />
</activity>
<activity
android:name="com.package.company.ClaimActivity"
android:theme="@style/AppTheme.NoActionBar"
tools:replace="android:theme" />
</application>
</manifest>
When targeting api 21 the compiler has a limit of 100 dex files it will read. 当针对api 21时,编译器将读取100个dex文件的限制。 So a simple solution I found was to add this to your dexOptions in your gradle file.
因此,我发现一个简单的解决方案是将其添加到gradle文件中的dexOptions中。 This will merge all your dex files into the lowest possible amount.
这会将所有dex文件合并到尽可能低的数量。
In your build.gradle file add the following 在build.gradle文件中添加以下内容
android {
...
dexOptions {
preDexLibraries = false
}
}
This means your multiDex does not work properly so some files are missing. 这意味着您的multiDex无法正常工作,因此缺少某些文件。 I think android 5.0 has the different way to use the multiDex.
我认为android 5.0有不同的方式来使用multiDex。 Did you override something in your Aplication class?
你是否覆盖了Aplication类中的某些内容?
Try removing compile 'com.android.support:multidex:1.0.1'
. 尝试删除
compile 'com.android.support:multidex:1.0.1'
。 The Google doc says 谷歌医生说
Therefore, if your minSdkVersion is 21 or higher, you do not need the multidex support library.
因此,如果您的minSdkVersion为21或更高,则不需要multidex支持库。
I am by no means sure if this helps, but it may be worth trying. 我不确定这是否有帮助,但它可能值得尝试。
For some reason, this class is not in your main dex anymore. 由于某种原因,这个课不再是你的主要dex了。
Declare the class in the main-classes list , using multiDexKeepFile (listing the classes in gradle) or multiDexKeepProguard (pointing to a specific proguard file for the main classes). 使用multiDexKeepFile (在gradle中列出类)或multiDexKeepProguard (指向主类的特定proguard文件) 在main-classes列表中声明类。
Try enabling Progaud and disabling multidex. 尝试启用Progaud并禁用multidex。
You'll not only fix this problem, but you'll have a smaller apk with faster install and run times. 你不仅可以修复这个问题,而且你会有一个更小的apk,安装和运行时间更快。
Note, If you need help with this just leave a comment and we can work it out. 注意,如果您需要帮助,请发表评论,我们可以解决。
The error is that com.package.Application is missing. 错误是缺少com.package.Application。 None of the code you posted (or the manifest) contains a reference to that class.
您发布的代码(或清单)都没有包含对该类的引用。 Where are you defining com.package.Application?
你在哪里定义com.package.Application? and if you aren't where in your project is it being referenced?
如果你不是在你的项目中被引用的地方? (I'd do a project wide search for "com.package.Application" to unravel this.)
(我会在项目范围内搜索“com.package.Application”来解开这个。)
try giving full path in manifest- 尝试在清单中给出完整的路径
<application
android:name=".TestApplication"
Also delete the build folder manually-sometimes clean doesn't work.Also uninstall the app manually and start. 同时手动删除构建文件夹 - 有时干净不起作用。也可以手动卸载应用程序并启动。
I have made demo from your code and configuration and its working in below marshmallow 我已经从你的代码和配置中进行了演示 ,并在marshmallow下面进行了工作
Download and check it and compare with your code. 下载并检查它并与您的代码进行比较。 And one more thing how you have created project with package name com.package.testapp.
还有一件事是你如何使用包名com.package.testapp创建项目。 I am not able to create project with same package name
我无法使用相同的包名创建项目
Create multidex-config.txt to keep this classes in the primary DEX file: 创建multidex-config.txt以将此类保留在主DEX文件中:
com/package/Application.class
com/package/TestApplication.class
com/package/testapp/welcome/TestClaimApplication.class
Add multiDexKeepFile to android.buildTypes.release section of your build.gradle like this: 添加multiDexKeepFile您的build.gradle这样的android.buildTypes.release部分:
android {
buildTypes {
release {
multiDexKeepFile file 'multidex-config.txt'
}
}
}
Do you need multidex enabled? 你需要启用multidex吗? I have always run into issues with it.
我一直遇到问题。 I always understood multidex to be used as a last resort if you are still hitting the 65k method limit.
如果您仍然达到65k方法限制,我总是理解multidex用作最后的手段。 If you are not running into this method limit, you do not need multidex.
如果您没有遇到此方法限制,则不需要multidex。 If you are running into this limit, I would suggest using progaurd to remedy the issue first.
如果你遇到这个限制,我建议先使用progaurd来解决这个问题。 If you are still above the method limit even after using proguard, then use multidex.
如果使用proguard后仍然高于方法限制,则使用multidex。
You need to add your android:name with complete path like this. 你需要添加你的android:name这样的完整路径。
android:name="android.support.multidex.MultiDexApplication"
And your TestApplication should extend MultiDexApplication. 并且您的TestApplication应该扩展MultiDexApplication。
According to the documentation, please refer if need more details. 根据文档,如果需要更多细节,请参考。 MultiDex Documentation
MultiDex文档
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.