0

I'm creating an app where you can input data that is stored in a room database, then displayed in a recyclerView. However, I keep getting java.lang.NullPointerException on the code that should add the inputs to the recyclerView adapter

I've set up the room database using this tutorial https://codelabs.developers.google.com/codelabs/android-room-with-a-view/#10 and altering the code slightly to fit my own use. I've looked at the question What is a NullPointerException, and how do I fix it? and learned what the error means, but I don't understand how to solve it for my code in particular (I'm still a beginner at android studio sorry)

input.java


    public static final String EXTRA_REPLY = "com.example.android.mysugartrackersql.REPLY";
    private EditText mEditInputView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_input);
        mEditInputView = findViewById(R.id.bgl_input);

        final Button button = findViewById(R.id.submit);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                Intent replyIntent = new Intent();
                if (TextUtils.isEmpty(mEditInputView.getText())) {
                    setResult(RESULT_CANCELED, replyIntent);
                } else {
                    String input1 = mEditInputView.getText().toString();
                    replyIntent.putExtra(EXTRA_REPLY, input1);
                    setResult(RESULT_OK, replyIntent);
                }
                finish();
            }
        });

    }

InputListAdapter.java


import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class InputListAdapter extends RecyclerView.Adapter<InputListAdapter.InputViewHolder> {

    class InputViewHolder extends RecyclerView.ViewHolder {
        private final TextView input1ItemView;

        private InputViewHolder(View itemView) {
            super(itemView);
            input1ItemView = itemView.findViewById(R.id.textView);
        }
    }

    private final LayoutInflater mInflater;
    private List<Input1> mInput1s; // Cached copy of words

    InputListAdapter(Context context) { mInflater = LayoutInflater.from(context); }

    @Override
    public InputViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = mInflater.inflate(R.layout.inputlist_item, parent, false);
        return new InputViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(InputViewHolder holder, int position) {
        if (mInput1s != null) {
            Input1 current = mInput1s.get(position);
            holder.input1ItemView.setText(current.getInput1());
        } else {
            // Covers the case of data not being ready yet.
            holder.input1ItemView.setText("No Input");
        }
    }

    void setInput1s(List<Input1> input1s){
        mInput1s = input1s;
        notifyDataSetChanged();
    }

    // getItemCount() is called many times, and when it is first called,
    // mInputs has not been updated (means initially, it's null, and we can't return null).
    @Override
    public int getItemCount() {
        if (mInput1s != null)
            return mInput1s.size();
        else return 0;
    }

}

Table.java (fragment where the recyclerView is displayed)


    public Table() {
        // Required empty public constructor
    }

    private RecyclerView mRecyclerView;
    private InputListAdapter mAdapter;
    private InputViewModel mInputViewModel;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        InputRoomDatabase db = Room.databaseBuilder(getActivity(),InputRoomDatabase.class, "input_database")
                .build();
        //add recycler view
        final View rootView = inflater.inflate(R.layout.fragment_table, container, false);
        RecyclerView recyclerView = rootView.findViewById(R.id.recyclerview);
        //set adapter
        final InputListAdapter adapter1 = new InputListAdapter(getContext());
        recyclerView.setAdapter(adapter1);
        //set layout manager
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        //show input list in recycler view
        mInputViewModel = ViewModelProviders.of(this).get(InputViewModel.class);
        mInputViewModel.getAllInput1s().observe(this, new Observer<List<Input1>>() {
            @Override
            public void onChanged(@Nullable final List<Input1> input1s) {
                // Update the cached copy of the words in the adapter.
                adapter1.setInput1s(input1s);
            }
        });

        // Inflate the layout for this fragment
        //return inflater.inflate(R.layout.fragment_table, container, false);
        return rootView;
    }

}

Tabbed.java (base fragment class) (this isn't the full class, only the relevant code)

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == INPUT_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
            Input1 input1 = new Input1(data.getStringExtra(input.EXTRA_REPLY));
            **mInputViewModel.insert(input1);**
            } else {
                Toast.makeText(
                        getApplicationContext(),
                        R.string.empty_not_saved,
                        Toast.LENGTH_LONG).show();
                }
        }
    public static final int INPUT_ACTIVITY_REQUEST_CODE = 1;

This is the logcat error:

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { (has extras) }} to activity {com.example.mysugartracker/com.example.mysugartracker.Tabbed}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.mysugartracker.InputViewModel.insert(com.example.mysugartracker.Input1)' on a null object reference

at com.example.mysugartracker.Tabbed.onActivityResult(Tabbed.java:111)

line 111 is marked with ** in the code

Birju Vachhani
  • 6,072
  • 4
  • 21
  • 43
  • 1
    Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – John3136 Aug 09 '19 at 04:49
  • @BreannaJury, `data.getStringExtra(input.EXTRA_REPLY)` check that value, it's getting null – ॐ Rakesh Kumar Aug 09 '19 at 04:52
  • Also add Logcat traces showing NullPointerException – sneharc Aug 09 '19 at 05:58
  • did you initialize your room db ? If you need to insert some values in your db you need to use threads. Using threads is not your solution. it is just an advice. You need to initialize your db wherever you use room db. – JDevoloper Aug 09 '19 at 06:24

2 Answers2

0

mInputViewModel = ViewModelProviders.of(this).get(InputViewModel.class);

This line is in Table.java not in Tabbed.java. So you created mInputViewModel in another class but used in Tabbed.java. If Table.java extends Tabbed.java remove this line from Table.java

private InputViewModel mInputViewModel;

faranjit
  • 1,567
  • 1
  • 15
  • 22
0

Thanks for the help everyone. I fixed the issue by adding this line mInputViewModel = ViewModelProviders.of(this).get(InputViewModel.class); in Tabbed.java