-2

I seem to be having a weird issue here. I have an ArrayList with a custom adapter that has 5 text-views. I am able to add to this list just fine the first time and save it and even reload it however after reloading it my Adapter class is throwing a null pointer on a getter method when attempting to add another item to the list. NUll pointer I know, but is the issue coming from attempting to add another item to the list? Is my adapter class only good for 1 view? Im at a loss as to why it is null or why it is at first then it isn't. Here is the stack trace

updated stack trace

08-04 14:23:17.855 10000-10000/com.apklegion.cltoollog E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.apklegion.cltoollog, PID: 10000
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.util.ArrayList.get(int)' on a null object reference
    at com.apklegion.cltoollog.ToolListAdapter.getView(ToolListAdapter.java:34)
    at android.widget.AbsListView.obtainView(AbsListView.java:2346)
    at android.widget.ListView.measureHeightOfChildren(ListView.java:1281)
    at android.widget.ListView.onMeasure(ListView.java:1188)
    at android.view.View.measure(View.java:18805)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:716)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:462)
    at android.view.View.measure(View.java:18805)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
    at android.view.View.measure(View.java:18805)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
    at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:400)
    at android.view.View.measure(View.java:18805)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at android.view.View.measure(View.java:18805)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
    at android.view.View.measure(View.java:18805)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643)
    at android.view.View.measure(View.java:18805)
    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2100)
    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1216)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1452)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
    at android.view.Choreographer.doCallbacks(Choreographer.java:670)
    at android.view.Choreographer.doFrame(Choreographer.java:606)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5417)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

and here is the adapter class where it says the error. updated to reflect the current error

public class ToolListAdapter extends ArrayAdapter<Toolinfo> {

 private Context mcontext;
int mResource;

public ToolListAdapter(Context context, int resource, ArrayList<Toolinfo> 
objects) {
    super(context, resource, objects);
    mcontext = context;
    mResource = resource;
}

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull 
ViewGroup parent) {

  -error is here>    String part_number = 
 objects.get(position).getPart_number();
    String serial_number = objects.get(position).getSerial_number();
    int employee_number = objects.get(position)).getEmployee_nummber();
    String date_out = objects.get(position).getOut_time();
    String date_in = objects.get(position).getIn_time();

    Toolinfo toolinfo = new Toolinfo(part_number,serial_number,employee_number,date_out,date_in);
    LayoutInflater layoutInflater = LayoutInflater.from(mcontext);
    convertView = layoutInflater.inflate(mResource,parent,false);

    TextView parnum = (TextView)convertView.findViewById(R.id.patnum);
    TextView sernum = (TextView)convertView.findViewById(R.id.sernum);
    TextView empnum = (TextView)convertView.findViewById(R.id.empnum);
    TextView timeout = (TextView)convertView.findViewById(R.id.timeout);
    TextView timein = (TextView)convertView.findViewById(R.id.timein);

    parnum.setText(part_number);
    sernum.setText(serial_number);
    empnum.setText(String.valueOf(employee_number));
    timeout.setText((date_out));
    timein.setText((date_in));
    return convertView;

}
}

here are the getters and setters

public class Toolinfo {

private String part_number;
private String serial_number;
private int employee_nummber;
private String out_time;
private String in_time;


public Toolinfo(String part_number, String serial_number, int employee_nummber, String out_time, String in_time){
    this.part_number = part_number;
    this.serial_number = serial_number;
    this.employee_nummber = employee_nummber;
    this.out_time = out_time;
    this.in_time = in_time;



}

public String getPart_number() {
    return part_number;
}

public void setPart_number(String part_number) {
    this.part_number = part_number;
}

public String getSerial_number() {
    return serial_number;
}

public void setSerial_number(String serial_number) {
    this.serial_number = serial_number;
}

public int getEmployee_nummber() {
    return employee_nummber;
}

public void setEmployee_nummber(int employee_nummber) {
    this.employee_nummber = employee_nummber;
}

public String getOut_time() {
    return out_time;
}

public void setOut_time(String out_time) {
    this.out_time = out_time;
}

public String getIn_time() {
    return in_time;
}

public void setIn_time(String in_time) {
    this.in_time = in_time;
}

} and last but not least the relevant bits of the main activity class where the ArrayList is held

public class MainActivity extends AppCompatActivity {

List<String> list = new ArrayList<>();
ArrayAdapter<String> adapter;
ListView listView;
Button button;
static  final int ADD_TOOL = 1;
CustomAdapter customAdapter;
public static final String PREFS_NAME = "MyPreferencesFile";
final String[] tools = {"30-200 Torque Wrench","Calipers","Push Pull Gague"};
String date_out,date_in;
String part_number,serial_number;
int employee_number;
Context context;
ArrayList<Toolinfo> toolinfos;
String currentDateandTime;
DatabaseHelper db;
Toolinfo tool1;

public static String TAG = "Main";

ToolListAdapter myadapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    toolinfos = new ArrayList<>();
    myadapter = new ToolListAdapter(this,R.layout.logrowlayout,toolinfos );





    loadData();


    button = findViewById(R.id.button);
    listView =  findViewById(R.id.listview);
    listView.setAdapter(myadapter);

    Intent getData = getIntent();
    if(getData.hasExtra("part number")&& getData.hasExtra("serial number") && getData.hasExtra("employee number")) {
        final String part_number = getData.getStringExtra("part number");
        showToast("has extras");

        String serial_number = getData.getStringExtra("serial number");
         showToast(serial_number);
        int employee_number = getData.getIntExtra("employee number", 0);
        // showToast(String.valueOf(employee_number));
        //addItems(part_number, serial_number, employee_number);

        SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy_HHmmss");
        String currentDateandTime = sdf.format(new Date());
        populateData(part_number,serial_number,employee_number,date_out,"out");

     }else {
    showToast("info not present");


}



    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            addTool();
        }
    });



}



public void populateData(String part_number,String serial_number,int employee_number, String date_out, String date_in) {
    //loadData();
    SimpleDateFormat sdf = new SimpleDateFormat("MMdd");
    String currentDateandTime = sdf.format(new Date());
    Toolinfo tool = new Toolinfo(part_number, serial_number, employee_number, currentDateandTime, "out");
    myadapter.add(tool);
    myadapter.notifyDataSetChanged();
    saveData(tool);

        for (int i = 0;  i < toolinfos.size(); i++) {
            Log.d(TAG, "populateData: " + toolinfos.get(i));


           //toolinfos.add(tool1);

        }

}

private  void saveData(Toolinfo tool1) {
    SharedPreferences preferences = getSharedPreferences("Shared prefs", MODE_PRIVATE);
    SharedPreferences.Editor editor = preferences.edit();
    Gson gson = new Gson();
    String json = gson.toJson(tool1);
    editor.putString("toolobj",json);
    showToast(json);
    editor.commit();



    //Log.i("tag",json.toString());
    editor.apply();
    showToast("Data Saved");

}
private void loadData(){
    SharedPreferences preferences = getSharedPreferences("Shared prefs", MODE_PRIVATE);
    Gson gson = new Gson();
    String json = preferences.getString("toolobj","");

    if (json == null){
        showToast("no data");

    }else {
        Toolinfo tool1 = gson.fromJson(json, Toolinfo.class);
        toolinfos.add(tool1);


    }




}
private void addTool(){

    Intent i = new Intent(MainActivity.this,Toolsignout.class);
    startActivity(i);
    saveData(tool1);



}
public void showToast(String msg){
    Toast.makeText(this,msg,Toast.LENGTH_LONG).show();
}

@Override
protected void onResume() {
  //  loadData();
    super.onResume();
}

}

apk legion
  • 21
  • 1
  • 10

2 Answers2

0

In your ToolsListAdapter add class variable for ArrayList<Toolinfo> objects; And assign similar to context.

And in your getView() method change getItem(position) to objects.get(position).

Gokul Nath KP
  • 15,485
  • 24
  • 88
  • 126
-1

You are only saving one object and loading one object to and from the SharedPreferences.

private  void saveData(Toolinfo tool1) {
    SharedPreferences preferences = getSharedPreferences("Shared prefs", MODE_PRIVATE);
    SharedPreferences.Editor editor = preferences.edit();
    Gson gson = new Gson();
    String json = gson.toJson(tool1);
    editor.putString("toolobj",json);
    showToast(json);
    editor.commit();

    editor.apply();
    showToast("Data Saved");

}
private void loadData(){
    SharedPreferences preferences = getSharedPreferences("Shared prefs", MODE_PRIVATE);
    Gson gson = new Gson();
    String json = preferences.getString("toolobj","");

    if (json == null){
        showToast("no data");
    }else {
        Toolinfo tool1 = gson.fromJson(json, Toolinfo.class);
        toolinfos.add(tool1);
    }
}

On your load method, json will never be equal to null. If the preferences didn't get an object it will return an empty string. Thus, will always go to the else block. Now, gson.fromJson wont throw any exception if the json is not a valid json or if it cant deserialize into a Toolinfo object. Instead, it will just return null. Thus, you are adding null to your list.

Also, keep in mind that:
Shared Preferences are key-value pairs. If you want to save List of Items or Records, you may want to look at Databases.

TL;DR
Your code is structured to save only one value, you could try saving the list to the shared preference. Change the if statement on your load method from checking if the json string is null to empy. And, do a check if the object is null before adding it to the list.

Jian Astrero
  • 744
  • 6
  • 19