Reputation: 97
Aim: I have a list of Object (custom class called Students), and I would like to update the attendance in each and every one (alters the Map field in the Students class). So, I want to exit the app, and when I relaunch it, I would like to have all the Students up to date. Thus, we can say that I want to save the data which is a list or array of (Students) to a file, and read it when the app relaunches.
Attempt: My Students class:
public class Students implements Serializable{
private int ID;
private int imageId;
private String firstName;
private String lastName;
private Map<Date, Boolean> Attendance;
public Students(int ID, String firstName, String lastName) {
this.ID = ID;
imageId = -1;//-1 indicates that there is no image
this.firstName = firstName;
this.lastName = lastName;
Attendance = new HashMap<>();
}
public Students(int ID, int imageId, String firstName, String lastName) {
this.ID = ID;
this.imageId = imageId;
this.firstName = firstName;
this.lastName = lastName;
Attendance = new HashMap<>();
}
public void putAttendance(Date d, Boolean b){
Attendance.put(d,b);
}
My Activity that reads/writes the data: (Mind you, I created this activity as a testing activity. So if the device is new, I want to have 8 students at first. So if the saving file doesn't exist, I will put 8 students in and save them). Nevertheless, let's go back to my code:
public class studentsAttendance extends AppCompatActivity {
private final String fileName = "data.bin";
private Teachers teacher;
private Students[] students = new Students[8];//sample of 8 students
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_students_attendance);
Bundle extras = getIntent().getExtras();
if (extras != null) {
teacher = (Teachers) getIntent().getSerializableExtra("Teachers"); //Obtaining the teacher
}
TextView tvWelcomeNote = (TextView) findViewById(R.id.tvWelcomeNote);
tvWelcomeNote.setText("Welcome " + teacher.getFirstName() + " " + teacher.getLastName());
File f = new File(this.getFilesDir().toString()+"/"+fileName);
if (!f.exists()) {
Toast.makeText(this, "File doesn't exist!", Toast.LENGTH_SHORT).show();
students = new Students[]{new Students(0, 0, "Barak", "Obama"),
new Students(1, 1, "Donald", "Trump"),
new Students(2, 2, "Sarah", "Franklin"),
new Students(3, 3, "Jack", "Johns"),
new Students(4, 4, "Aston", "Martin"),
new Students(5, 5, "Kaleb", "Philips"),
new Students(6, 6, "John", "Cena"),
new Students(7, 7, "Randy", "Orton")};
for(Students s: students){
this.saveStudent(s);
}
Toast.makeText(this, "Saved!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "File Exists", Toast.LENGTH_SHORT).show();
Students[] o = readStudent();
Log.d("", Arrays.deepToString(students));//->giving me [null,null,null.....]
Toast.LENGTH_SHORT).show();Toast.LENGTH_SHORT).show();
}
}
public Boolean saveStudent(Students s) {//saves student into fileName (data.bin)
ObjectOutputStream oos = null;
try {
File file = new File(this.getFilesDir().toString(), fileName);
file.createNewFile();
FileOutputStream fos = this.openFileOutput(fileName, this.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(s);
oos.close();
fos.close();
return true;
} catch (FileNotFoundException err) {
Toast.makeText(this, "Something went wrong while saving", Toast.LENGTH_SHORT).show();
return false;
} catch (Exception abcd) {
Toast.makeText(this, "Something went wrong while saving 2.0", Toast.LENGTH_SHORT).show();
return false;
}
finally {//makes sure to close the ObjectOutputStream
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public Students[] readStudent() {//reads Student[] object from(data.bin) and returns it.
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(new File(this.getFilesDir().toString()+"/"+fileName)));
Students[] temp = new Students[8];
for(int i=0;i<8;i++){
temp[i]=(Students) ois.readObject();
}
ois.close();
return temp;
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Logs:
05-21 22:46:02.941 11424-11424/? I/art: Not late-enabling -Xcheck:jni (already on)
05-21 22:46:02.941 11424-11424/? W/art: Unexpected CPU variant for X86 using defaults: x86
05-21 22:46:02.955 11424-11431/? I/art: Debugger is no longer active
05-21 22:46:02.955 11424-11431/? I/art: Starting a blocking GC Instrumentation
05-21 22:46:03.029 11424-11424/? W/System: ClassLoader referenced unknown path: /data/app/com.example.mohammadel_ghali.attendance-1/lib/x86
05-21 22:46:03.033 11424-11424/? I/InstantRun: starting instant run server: is main process
05-21 22:46:03.034 11424-11424/? V/InstantRun: Starting server socket listening for package com.example.mohammadel_ghali.attendance on android.net.LocalSocketAddress@6c32846
05-21 22:46:03.034 11424-11424/? V/InstantRun: Started server for package com.example.mohammadel_ghali.attendance
05-21 22:46:03.475 11424-11441/? V/InstantRun: Received connection from IDE: spawning connection thread
05-21 22:46:03.478 11424-11441/? V/InstantRun: Received Ping message from the IDE; returned active = false
05-21 22:46:03.479 11424-11441/? V/InstantRun: Received EOF from the IDE
05-21 22:46:05.289 11424-11424/com.example.mohammadel_ghali.attendance W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
05-21 22:46:05.452 11424-11534/com.example.mohammadel_ghali.attendance I/OpenGLRenderer: Initialized EGL, version 1.4
05-21 22:46:05.452 11424-11534/com.example.mohammadel_ghali.attendance D/OpenGLRenderer: Swap behavior 1
05-21 22:46:05.452 11424-11534/com.example.mohammadel_ghali.attendance W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
05-21 22:46:05.452 11424-11534/com.example.mohammadel_ghali.attendance D/OpenGLRenderer: Swap behavior 0
05-21 22:46:05.536 11424-11424/com.example.mohammadel_ghali.attendance W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
05-21 22:46:11.215 11424-11424/com.example.mohammadel_ghali.attendance W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: java.io.EOFException
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2604)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1319)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at com.example.mohammadel_ghali.attendance.studentsAttendance.readStudent(studentsAttendance.java:119)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at com.example.mohammadel_ghali.attendance.studentsAttendance.onCreate(studentsAttendance.java:69)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at android.app.Activity.performCreate(Activity.java:6679)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at android.app.ActivityThread.-wrap12(ActivityThread.java)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at android.os.Looper.loop(Looper.java:154)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6119)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at java.lang.reflect.Method.invoke(Native Method)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
05-21 22:46:13.978 11424-11424/com.example.mohammadel_ghali.attendance W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
[ 05-21 22:46:13.978 11424:11424 D/ ]
[null, null, null, null, null, null, null, null]
05-21 22:46:14.089 11424-11424/com.example.mohammadel_ghali.attendance W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
05-21 22:46:14.089 11424-11424/com.example.mohammadel_ghali.attendance W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
05-21 22:46:14.106 11424-11534/com.example.mohammadel_ghali.attendance D/OpenGLRenderer: endAllActiveAnimators on 0x93e27f00 (RippleDrawable) with handle 0x92d26040
If you can help me fix this problem, or suggest another easier way of fixing this problem, that would be great. Thank you.
Upvotes: 0
Views: 726
Reputation: 131
You're overwriting the previous student every time you save one. Instead, save the entire array to the file, and read it in all at once. Modify your `saveStudent' method to look like this:
public Boolean saveStudents(Students[] students) {//saves student into fileName (data.bin)
ObjectOutputStream oos = null;
try {
File file = new File(this.getFilesDir().toString(), fileName);
file.createNewFile();
FileOutputStream fos = this.openFileOutput(fileName, this.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(students);
oos.close();
fos.close();
return true;
} catch (FileNotFoundException err) {
Toast.makeText(this, "Something went wrong while saving", Toast.LENGTH_SHORT).show();
return false;
} catch (Exception abcd) {
Toast.makeText(this, "Something went wrong while saving 2.0", Toast.LENGTH_SHORT).show();
return false;
}
finally {//makes sure to close the ObjectOutputStream
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
And your readStudent
method to look like this:
public Students[] readStudents() {//reads Student[] object from(data.bin) and returns it.
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(new File(this.getFilesDir().toString()+"/"+fileName)));
Students[] temp = (Students[])ois.readObject();
ois.close();
return temp;
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
You will then write it like this:
saveStudents(students);
And read it back in like this:
Students[] o = readStudents();
Don't forget to delete the app to clear what you have in there now. Also, I would agree that you should be using a local database for this.
Upvotes: 1