应用程序崩溃是因为java访问修饰符-为什么?

应用程序崩溃是因为java访问修饰符-为什么?,java,android,android-lifecycle,Java,Android,Android Lifecycle,最近我写了一个简单的Android应用程序 该应用程序有一个简单的MainActivity和一个ViewModel。 在编写代码时,我确实将ViewModel类声明为public 就在我完成应用程序之前,我浏览了警告,看到一条警告说ViewModel类的访问修饰符可以变成package而不是public 当时我没有考虑太多,删除了public修饰符 我测试了应用程序,一切正常 然后我发布了一个版本,应用程序在启动时崩溃了。我没有联系到为什么会发生这种情况,但通过快速查看堆栈跟踪,我得到了它。 我

最近我写了一个简单的Android应用程序

该应用程序有一个简单的MainActivity和一个ViewModel。 在编写代码时,我确实将ViewModel类声明为public

就在我完成应用程序之前,我浏览了警告,看到一条警告说ViewModel类的访问修饰符可以变成package而不是public

当时我没有考虑太多,删除了public修饰符

我测试了应用程序,一切正常

然后我发布了一个版本,应用程序在启动时崩溃了。我没有联系到为什么会发生这种情况,但通过快速查看堆栈跟踪,我得到了它。 我将public修饰符添加回ViewModel类,一切都正常工作

因为ViewModel实际上是由我的包之外的提供者实例化的,所以ViewModel必须有一个公共修饰符

我的问题是,为什么我的应用程序在调试编译配置中正常工作,因为我预计它也会在那里崩溃

我的ViewModel:

import android.app.Application;
import android.util.Log;

import androidx.lifecycle.AndroidViewModel;

import java.util.ArrayList;
import java.util.Random;

public class TilesViewModel extends AndroidViewModel {
mViewModel = ViewModelProviders.of(this).get(TilesViewModel.class);
我创建的ViewModel:

import android.app.Application;
import android.util.Log;

import androidx.lifecycle.AndroidViewModel;

import java.util.ArrayList;
import java.util.Random;

public class TilesViewModel extends AndroidViewModel {
mViewModel = ViewModelProviders.of(this).get(TilesViewModel.class);
崩溃:

 Caused by: java.lang.RuntimeException: Cannot create an instance of class il.co.woo.karuba.TilesViewModel
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:234)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:164)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:130)
        at il.co.woo.karuba.MainActivity.onCreate(MainActivity.java:70)
        at android.app.Activity.performCreate(Activity.java:6679)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6119) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
     Caused by: java.lang.IllegalAccessException: java.lang.Class<il.co.woo.karuba.TilesViewModel> is not accessible from java.lang.Class<androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory>
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:230)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:164) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:130) 
        at il.co.woo.karuba.MainActivity.onCreate(MainActivity.java:70) 
        at android.app.Activity.performCreate(Activity.java:6679) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6119) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
原因:java.lang.RuntimeException:无法创建类il.co.woo.karuba.TilesViewModel的实例
在androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:234)
位于androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:164)
位于androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:130)
位于il.co.woo.karuba.MainActivity.onCreate(MainActivity.java:70)
位于android.app.Activity.performCreate(Activity.java:6679)
位于android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)上
位于android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
位于android.app.ActivityThread.-wrap12(ActivityThread.java)
在android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)上
位于android.os.Handler.dispatchMessage(Handler.java:102)
位于android.os.Looper.loop(Looper.java:154)
位于android.app.ActivityThread.main(ActivityThread.java:6119)
位于java.lang.reflect.Method.invoke(本机方法)
在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)上
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
原因:java.lang.IllegalAccessException:java.lang.Class无法从java.lang.Class访问
位于java.lang.reflect.Constructor.newInstance0(本机方法)
位于java.lang.reflect.Constructor.newInstance(Constructor.java:430)
在androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:230)
位于androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:164)
位于androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:130)
位于il.co.woo.karuba.MainActivity.onCreate(MainActivity.java:70)
位于android.app.Activity.performCreate(Activity.java:6679)
位于android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)上
位于android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
位于android.app.ActivityThread.-wrap12(ActivityThread.java)
在android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)上
位于android.os.Handler.dispatchMessage(Handler.java:102)
位于android.os.Looper.loop(Looper.java:154)
位于android.app.ActivityThread.main(ActivityThread.java:6119)
位于java.lang.reflect.Method.invoke(本机方法)
在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)上
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

例如,与ViewModel创建相关的原因有很多

  • 您没有对类或构造函数使用公共访问修饰符,factory可能无法创建它的实例
  • 您扩展了错误的ViewModel
  • ViewModel参数化构造函数也可能由于无法在构造函数中创建其他注入对象而产生问题
  • 但是在您的情况下,在Debug中工作而不是在Release中工作可能是由于Proguard截断了未使用的访问修饰符或构造函数,这可能会导致此问题


    一些更详细的信息会很有用,比如gradle文件中的依赖项行、这个
    ViewModel
    类的包、stacktrace等等。为什么不看看crashlog看看问题出在哪里呢?@Zun I添加了崩溃日志和代码。崩溃日志确实解释了这个问题。但是为什么它没有发生在调试中?@Kartik-添加了代码示例和崩溃日志我理解你对ProGuard的看法,但感觉正好相反,因为我是第一个删除公共修饰符的人,我希望它在有或没有ProGuard的情况下崩溃,因为Android如何实例化我的ViewModel。。。