0

New to Java so sorry for my poor understanding. I have hit a small snag, I have a static class for connecting to a server. I am using another class for SharedPreferences, some of the details of the SharedPreferences are the servers address to connect to.

As I have come to use the SharedPreferences class inside my static Connection class, I am hit with a flaw where I cannot use a non static field in a static context.

Is there anyway around this? Can I set the value to be static? Or is there anyway to load the values in and keep them static?

I would fetch my SharedPreferences from any activity:

String sName = SharedPrefs.getserverName(this);

But anyway I reference this in my static Connection class I am lumbered with:

None-Static field XXXXXX cannot be referenced from a static context

(Obviously I cannot just include the word static before hand as it fails because of "this cannot be referenced from static context".)

SharedPreference class:

private static SharedPreferences getPrefs(Context context) {
    return context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
}

public static String getserverName(Context context) {
    return getPrefs(context).getString("server_name", "");
}

I believe I have used the static correctly.

Connection Class as requested:

public class ConnectionManager extends AppCompatActivity {
    static StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    static String serverName = SharedPrefs.getserverName(Context);
//  static String serverName ="192.168.1.105";   //TODO Ensure Database details loaded from Shared Preferences
    static String serverPort ="1433";
    static String databaseName ="DBANAME";
    static String db = String.format("jdbc:jtds:sqlserver://%s:%s/%s", serverName, serverPort, databaseName);
    static String un = "sa";
    static String pass = "";
    static Connection con;


    public static Connection getConnection() {

        try {
            try {
                StrictMode.setThreadPolicy(policy);
                Class.forName("net.sourceforge.jtds.jdbc.Driver");
                con = DriverManager.getConnection(db, un, pass);
            } catch (SQLException ex) {
                // log an exception. fro example:
                System.out.println("Failed to create the database connection.");
            }
        } catch (ClassNotFoundException ex) {
            // log an exception. for example:
            System.out.println("Driver not found.");
        }
        return con;
    }
}

Enquiry Activity (Calls the Database Connection Class)

        try {

            con = ConnectionManager.getConnection();
            if (con == null) {
                z = "Check Your Internet Access!";
                Toast.makeText(StockEnquiry.this, z, Toast.LENGTH_LONG).show();
            } else 

Updated

After the help from user1506104 i got this working. I moved the Call for SharedPref to inside the getConnection and included Context context. Like so:

public static Connection getConnection(Context context) {
String serverName = SharedPrefs.getserverName(context);
String serverPort = SharedPrefs.getserverPort(context);
String databaseName = SharedPrefs.getdatabaseName(context);
String sPath = SharedPrefs.getserverPath(context);
String db = String.format("jdbc:jtds:sqlserver://%s:%s/%s", serverName, serverPort, databaseName);
try {
    try {
        StrictMode.setThreadPolicy(policy);
        Class.forName("net.sourceforge.jtds.jdbc.Driver");
        con = DriverManager.getConnection(db, un, pass);
    } catch (SQLException ex) {
        // log an exception. fro example:
        System.out.println("Failed to create the database connection.");
    }
} catch (ClassNotFoundException ex) {
    // log an exception. for example:
    System.out.println("Driver not found.");
}
return con;

}

Then in my Activity, I just needed to include this in the getConnection() Like so:

   con = ConnectionManager.getConnection(this);

Thank you for your time :)

Dave Hamilton
  • 675
  • 1
  • 12
  • 23
  • 1
    Does this answer your question? [What is the reason behind "non-static method cannot be referenced from a static context"?](https://stackoverflow.com/questions/290884/what-is-the-reason-behind-non-static-method-cannot-be-referenced-from-a-static) – Nikos Hidalgo Dec 16 '19 at 17:02
  • Is your PREF_NAME a static variable? – user1506104 Dec 16 '19 at 17:08
  • Can you show the code in `Connection` class where you get the error from compiler? – Son Truong Dec 17 '19 at 02:58
  • @Nhất Giang Updated Connection Class, Line fails on: static String serverName = SharedPrefs.getserverName(Context); – Dave Hamilton Dec 17 '19 at 12:09

2 Answers2

1

This code is okay if you are calling from inside an activity because the this keyword refers to your current activity instance.

String sName = SharedPrefs.getserverName(this);

Make sure that you have a reference to the context object inside your static Connection class. Let's say your context object is referenced by the context variable, do this:

String sName = SharedPrefs.getserverName(context);
user1506104
  • 6,554
  • 4
  • 71
  • 89
  • you have to pass the `context` to your Connection class. You can do like so: `public static Connection getConnection(Context context) {...` – user1506104 Dec 17 '19 at 12:16
  • then when i call it i would need: con = ConnectionManager.getConnection(Context context); or not? Think i may be in a pickle, as i use Context context in a previous Broadcaster receiver event. I could show you the full source if you would take a look? – Dave Hamilton Dec 17 '19 at 13:23
  • Yes you need to provide the context via getConnection(context); – user1506104 Dec 17 '19 at 13:47
  • So i updated it again to show the Activity that calls the Connection Class to establish a Database connection. When i remove things from being Static the compiler complains: error: non-static method getConnection() cannot be referenced from a static context All-though i do not see anything referenced to Static in my Enquiry Activity. I tried this yesterday, All because i dont want to repeat the same connection code over and over, i want to do it properly from a Class, But that class wont load my preferences in the format required :( – Dave Hamilton Dec 17 '19 at 13:57
  • Also in your StockEnquiry activity, do this: con = ConnectionManager.getConnection(this); – user1506104 Dec 17 '19 at 14:35
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/204415/discussion-between-dave-hamilton-and-user1506104). – Dave Hamilton Dec 17 '19 at 14:46
0

Please use Singleton Design pattern. It is a good programming practise. Creating static class has the above issue. Here is a blog for singleton pattern in Android https://medium.com/@programmerr47/singletons-in-android-63ddf972a7e7

Kailash Chivhe
  • 243
  • 3
  • 7