0
\$\begingroup\$

This is a follow-up question for Android app class serialization. As forsvarir's updated answer mentioned "A static load that returns a new instance of a User might be closer, or a better solution would probably be to move the save/load logic out of the user class altogether into a class that knows about loading/saving.", Thus, I am attempting to re-design the serialization part with static methods. The Load and Save methods are removed from User class and another Serialization class has been created for the static version Load and Save methods. (If I misunderstand something, please let me know.)

The experimental implementation

  • Project name: UserClassStaticLoadSave

  • User class implementation:

    package com.example.userclassstaticloadsave;
    
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    public class User  implements java.io.Serializable {
         private String fullName;
         private String personalID;
         private String dateOfBirth;
         private String cellPhoneNumber;
         private String emailInfo;
         private String password;
    
    
         public User(final String fullNameInput,
                     final String personalIDInput,
                     final String dateOfBirthInput,
                     final String cellPhoneNumberInput,
                     final String emailInfoInput,
                     final String passwordInput) {
             fullName = fullNameInput;
             personalID = personalIDInput;
             dateOfBirth = dateOfBirthInput;
             cellPhoneNumber = cellPhoneNumberInput;
             emailInfo = emailInfoInput;
             try {
                 password = hashingMethod(passwordInput);
             } catch (Exception ex) {
                 password = passwordInput;
             }
             return;
         }
    
         public String getFullName() {
             return fullName;
         }
    
         public String getPersonalID() {
             return personalID;
         }
    
         public String getDateOfBirth() {
             return dateOfBirth;
         }
    
         public String getCellPhoneNumber() {
             return cellPhoneNumber;
         }
    
         public String getEmailInfo() {
             return emailInfo;
         }
    
         public String getHash() throws NoSuchAlgorithmException {
             return hashingMethod(fullName + personalID);
         }
    
         public String getHashedPassword() throws NoSuchAlgorithmException {
             return password;
         }
    
         public boolean checkPassword(String password) {
             boolean result = false;
             try {
                 result = password.equals(hashingMethod(password));
             }
             catch (Exception e) {
                 e.printStackTrace();
             }
             return result;
         }
    
         //**********************************************************************************************
    
         //  Reference: https://stackoverflow.com/a/2624385/6667035
         private String hashingMethod(String inputString) throws NoSuchAlgorithmException {
             MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
             String stringToHash = inputString;
             messageDigest.update(stringToHash.getBytes());
             String stringHash = new String(messageDigest.digest());
             return stringHash;
         }
    }
    
  • Serialization class implementation:

    package com.example.userclassstaticloadsave;
    
    import android.content.Context;
    import android.util.Log;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    
    public class Serialization {
    
         //  Reference: https://stackoverflow.com/a/4118917/6667035
         //  fileName cannot contain any path separator
         public static boolean save(Context context, String fileName, User user) {
             try {
                 FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
                 String fullFilename = context.getFilesDir() + "/" + fileName;
                 Log.d("save", "save file in " + fullFilename);
                 ObjectOutputStream os = new ObjectOutputStream(fos);
                 os.writeObject(user);
                 os.close();
                 fos.close();
                 if (new File(fullFilename).exists()) {
                     return true;
                 } else {
                     return false;
                 }
             } catch (IOException i) {
                 i.printStackTrace();
                 return false;
             }
         }
    
         public static User load(Context context, String fileName) {
             try {
                 FileInputStream fis = context.openFileInput(fileName);
                 ObjectInputStream is = new ObjectInputStream(fis);
                 User simpleClass = (User) is.readObject();
                 is.close();
                 fis.close();
                 return simpleClass;
             } catch (Exception e){
                 e.printStackTrace();
             }
             return null;
         }
    }
    
  • build.gradle:

    plugins {
        id 'com.android.application'
    }
    
    android {
        compileSdk 31
    
        defaultConfig {
            applicationId "com.example.userclassstaticloadsave"
            minSdk 26
            targetSdk 31
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_11
            targetCompatibility JavaVersion.VERSION_11
        }
    }
    
    dependencies {
    
        implementation 'androidx.appcompat:appcompat:1.3.1'
        implementation 'com.google.android.material:material:1.4.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    }
    

Full Testing Code

  • MainActivity.java implementation:

    package com.example.userclassstaticloadsave;
    
    import androidx.annotation.StringRes;
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.content.Context;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            User currentUser = new User(
                    "Mike",
                    "M12345678",
                    "1990/10/13",
                    "(555) 555-1234",
                    "123456@test.com",
                    "password");
            boolean isSaveSuccessfully = Serialization.save(this, "User.ser", currentUser);
            if (isSaveSuccessfully) {
                showToast("save current user information successfully", Toast.LENGTH_SHORT);
                Log.d("save operation", "save current user information successfully");
            }
            showToast(Serialization.load(this, "User.ser").getFullName(), Toast.LENGTH_SHORT);
    
        }
    
        private void showToast(@StringRes int res, int duration) {
            showToast(getResources().getString(res), duration);
            return;
        }
    
        private void showToast(String textInput, int duration)
        {
            Context context = getApplicationContext();
            CharSequence text = textInput;
            Toast toast = Toast.makeText(context, text, duration);
            toast.show();
        }
    }
    

All suggestions are welcome.

The summary information:

  • Which question it is a follow-up to?

    Android app class serialization

  • What changes has been made in the code since last question?

    I am attempting to re-design the serialization part with static methods. The Load and Save methods are removed from User class and another Serialization class has been created for the static version Load and Save methods.

  • Why a new review is being asked for?

    If there is any possible improvement, please let me know.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.