0

so basically I have several different Java classes in Android studio. One of these classes contains a host of functions that I need to call from different classes based on what the user selects. My issue is that I need the class that I'm calling these functions from, to remember its variable values. This is an exact example of the class that contains all of the functions that I need to call, one important variable is Logged.

A solution would have been to call the class from every class that needs access to it, but that would require Classy classy= new Classy(); which would then reset the variables to null.

public class Classy {
private String snumber;
private String spassword;
public Context context;
private boolean logged = false;

public String getSnumber() {
    return snumber;
}

public String getSpassword() {
    return spassword;
}

public void setContext(Context context) {
    this.context = context;
}

public void setSnumber(String snumber) {
    this.snumber = snumber;
}

public void setSpassword(String spassword) {
    this.spassword = spassword;
}

public boolean getLogged() {
    return logged;
}

public void setLogged(boolean logged) {
    this.logged = logged;
}

public boolean Read() {

    try {
        InputStream inputStream = context.openFileInput("COHFTW.txt");
        if (inputStream != null) {
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String receiveString = "";
            StringBuilder stringBuilder = new StringBuilder();

            while ((receiveString = bufferedReader.readLine()) != null) {
                stringBuilder.append(receiveString);
            }
            inputStream.close();
            String contents = stringBuilder.toString();
            if (contents.isEmpty()) {
                return false;
            } else {
                snumber = contents.substring(0, contents.indexOf("#"));
                spassword = contents.substring(contents.indexOf("#") + 1);
            }
        }
    } catch (FileNotFoundException e) {
        System.out.println("_______________File Not Found_________________");
        return false;

    } catch (IOException e) {
        System.out.println("________________File Unreadable________________");
        return false;

    }

    return true;
}


public boolean ClearFile() {


    try {
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput("COHFTW.txt", Context.MODE_PRIVATE));

        outputStreamWriter.write("");
        outputStreamWriter.close();
        System.out.println("________________________File Cleared________________");
        return true;

    } catch (Exception e) {
        System.out.println("________________Error:" + e + "________________");

        return false;

    }

}


public boolean Write() {

    System.out.println("________________Writing" + snumber + " " + spassword + "________________");

    try {
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput("COHFTW.txt", Context.MODE_PRIVATE));

        outputStreamWriter.write(snumber + "#" + spassword);
        outputStreamWriter.close();
        System.out.println("________________________Saved: " + snumber + "#" + spassword + "________________");
        return true;

    } catch (Exception e) {
        System.out.println("________________Error:" + e + "________________");

        return false;

    }

}

}

Any help would be appreciated, because currently I'm reading from a text-file every time I want to access a web-page (Name and password are taken from the text-file) and it's causing some serious lag.

Jamie A-Reade
  • 107
  • 1
  • 5

3 Answers3

3

This sounds like a perfect use case for a Singleton class!

First create a private static instance of your class.

public class Classy {
    private static Classy instance;

Next create a private constructor and public method to call that constructor

private Classy(){ /*... */ }

public void instantiate(){
    if(instance != null) return;
    instance = new Classy();
} 

Finally create a method to get your singleton

public static Classy getInstance() {
    // Optionally include a null check
    // if(instance == null) instantiate();
    return instance;
}

The end result allows you to access your values across any class like so:

Classy.getInstance().getSpassword()
Chris Stillwell
  • 10,266
  • 10
  • 67
  • 77
  • Much appreciated for the help :D Someone else recommended that I pass the class as an object between fragments, but that sounded like it would create multiple bugs. – Jamie A-Reade Aug 05 '18 at 13:26
1

Your wording is a little weird in the question, but if I understand correctly I think you want to use class variables instead of instance variables. All you have to do is add the static keyword to your variables and methods that you define in the class and access the variables by the class instead of the instance.


Like this:
private static String snumber;
private static String spassword;
private static boolean logged = false;
public static String getSnumber() {
    return Classy.snumber;
}

public static String getSpassword() {
    return Classy.spassword;
}

public static void setContext(Context context) {
    Classy.context = context;
}

public static void setSnumber(String snumber) {
    Classy.snumber = snumber;
}

public static void setSpassword(String spassword) {
    Classy.spassword = spassword;
}

public static boolean getLogged() {
    return Classy.logged;
}

public static void setLogged(boolean logged) {
    Classy.logged = logged;
}
/* The rest of your code */

This way, the variables are not dependent on the instance of the class you create, instead they are only owned by the class itself.

But now you cannot do Classy classy = new Classy(); because that will make a new instance and it will have no instance variables.

Happy Coding!

agillgilla
  • 859
  • 1
  • 7
  • 22
1

I have several different Java classes in Android studio. One of these classes contains a host of functions that I need to call from different classes based on what the user selects. My issue is that I need the class that I'm calling these functions from, to remember its variable values. [...]

A solution would have been to call the class from every class that needs access to it, but that would require Classy classy= new Classy(); which would then reset the variables to null.

Class Classy's methods are all instance methods, not class methods, so the only way you can invoke them is on an instance. Each instance will retain the values of its variables for its lifetime, subject to changes made via its methods (or directly, in the case of public variable context).

The solution, then, is to create and retain a separate Classy instance in each scope that requires distinct Classy values, but not more than one. In particular, from your description, it sounds like methods of other classes indeed should not create their own instances, just as you say.

The question may then boil down to how to retain Classy instances across methods, but that's pretty simple: you use an instance variable, or possibly a class variable, of some other class. Perhaps one for each other class that uses Classy, if each needs to retain its own set of Classy variables. Or if every other class should use the same Classy instance, then you could also make it a class variable of the Classy class itself -- that's the core of the "Singleton" pattern.

Community
  • 1
  • 1
John Bollinger
  • 160,171
  • 8
  • 81
  • 157