【问题标题】:NullPointerException in simple ViewModel project简单 ViewModel 项目中的 NullPointerException
【发布时间】:2018-09-18 09:07:10
【问题描述】:

我为了保存仲裁对象的数据,我创建了一个 ViewHolder 模式。但是,我的 ViewHolder 不断收到 NullPointerException。


简单对象类

public class Action {

public Action() {
}

public String activity;

}

视图模型:

public class Action_ViewModel extends ViewModel{

public Action action;

public Action_ViewModel () {
    Action action = new Action();
}

public Action getAction() {
    return action;
}

public void setActivity(String activity) {
    action.activity = activity;
}

}

活动(vm.setActivity 上的 NullPointer):

  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        savedInstanceState.getBoolean(STATE_CHOOSER);

    setContentView(R.layout.create_actions);

    Action_ViewModel vm = ViewModelProviders.of(this).get(Action_ViewModel.class);

    //Autocomplete za select Actiona
    AutoCompleteTextView chooser = findViewById(R.id.choose_action_complete);
    String[] allActions = getResources().getStringArray(R.array.autocomplete_createAction);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, allActions);
    chooser.setAdapter(adapter);
    chooser.setOnItemClickListener((AdapterView<?> parent, View view, int p

osition, long id) -> {
            vm.setActivity(allActions[position]);
            ACTION_CHOOSER = true;
        });

堆栈跟踪:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.android.activities, PID: 15667
                  java.lang.NullPointerException: Attempt to write to field 'java.lang.String com.example.android.activities.Action.activity' on a null object reference
                      at com.example.android.activities.Action_ViewModel.setActivity(Action_ViewModel.java:22)
                      at com.example.android.activities.CreateAction.lambda$onCreate$0$CreateAction(CreateAction.java:35)
                      at com.example.android.activities.CreateAction$$Lambda$0.onItemClick(Unknown Source:46)
                      at android.widget.AutoCompleteTextView.performCompletion(AutoCompleteTextView.java:1017)
                      at android.widget.AutoCompleteTextView.-wrap1(Unknown Source:0)
                      at android.widget.AutoCompleteTextView$DropDownItemClickListener.onItemClick(AutoCompleteTextView.java:1313)
                      at android.widget.AdapterView.performItemClick(AdapterView.java:318)
                      at android.widget.AbsListView.performItemClick(AbsListView.java:1165)
                      at android.widget.AbsListView$PerformClick.run(AbsListView.java:3134)
                      at android.widget.AbsListView$3.run(AbsListView.java:4049)
                      at android.os.Handler.handleCallback(Handler.java:789)
                      at android.os.Handler.dispatchMessage(Handler.java:98)
                      at android.os.Looper.loop(Looper.java:164)
                      at android.app.ActivityThread.main(ActivityThread.java:6541)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

请检查代码并帮助我解决这个问题,因为我已经尝试了我自己能记住的一切。谢谢。

【问题讨论】:

  • 能否分享一下错误日志
  • 我已将代码更改为更简单的情况,请看一下这个。 @PrithviBhola
  • java.lang.NullPointerException:尝试在空对象引用上写入字段“java.lang.String com.example.android.activities.Action.activity”
  • 您的ViewModel vm 未正确启动。你是如何在activity 中启动ViewModel 的?
  • 使vm 成为您活动中的字段,而不是onCreate() 中的局部变量。您可能还想收紧代码以确保您不会在某个地方意外弄乱某些东西,例如在您的视图模型中将 action 设置为 final 并将其初始化为内联 (final public Action action = new Action();) 而不是在构造函数中。这样,如果问题中没有显示将action重置为null的代码,则会出现编译错误。

标签: java android mvvm data-binding android-livedata


【解决方案1】:

要实例化 ViewModel,您需要 ViewModelFactory

@Inject
ViewModelProvider.Factory viewModelFactory;

Action_ViewModel vm = ViewModelProviders.of(this, viewModelFactory).get(modelClass)

ViewModelFactory

    @Singleton
    public class ViewModelFactory implements ViewModelProvider.Factory {

    private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;

    @Inject
    public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
        this.creators = creators;
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T extends ViewModel> T create(Class<T> modelClass) {
        Provider<? extends ViewModel> creator = creators.get(modelClass);
        if (creator == null) {
            for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
                if (modelClass.isAssignableFrom(entry.getKey())) {
                    creator = entry.getValue();
                    break;
                }
            }
        }
        if (creator == null) {
            throw new IllegalArgumentException("unknown model class " + modelClass);
        }
        try {
            return (T) creator.get();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

ViewModelKey

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@MapKey
public @interface ViewModelKey {
    Class<? extends ViewModel> value();
}

ViewModel 模块

@Module
public abstract class ViewModelModule {

    @Binds
    @IntoMap
    @ViewModelKey(Action_ViewModel.class)
    public abstract ViewModel bindsHomeActivityModel(Action_ViewModel actionViewModel);

    @Binds
    public abstract ViewModelProvider.Factory viewModelFactoryProvider(ViewModelFactory factory);

}

注意:以上代码使用Dagger

【讨论】:

  • 为什么我需要一个工厂方法来创建虚拟机?这不应该只在创建 (Android)VM 中不可用的构造函数时使用吗?
  • @Androidz 否。要实例化 ViewModel,您需要实现 ViewModelProvider.Factory 的 ViewModelFactory,它将根据参数创建 ViewModel。 developer.android.com/reference/android/arch/lifecycle/…
  • 即使我添加了一个工厂(我使用了一个更简单的工厂),它仍然会崩溃并出现同样的异常。
  • 该解决方案应该有效。这就是我实现的方式和 android 文档给出的方式。确保您已正确实施它
猜你喜欢
  • 2022-01-20
  • 2013-03-16
  • 2011-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-15
  • 2013-01-05
  • 1970-01-01
相关资源
最近更新 更多