0

I want to access variable value of normal Android Activity in the Java Class.

First
I have String name link_sp in which I have value of url link that I have stored in SharedPreferences

MainActivity.java

SharedPreferences sp;
String link_sp;
public static String linkUrl = "";

// onCreate Method {
...
sp       = getSharedPreferences("MySharedPref", MODE_PRIVATE);
link_sp  = sp.getString("link", "");
// Setting value of link_sp to static string linkUrl
linkUrl  = link_sp;

...
}
// Also I have this method in MainActivity
public static String getLink() {
        return linkUrl;
}

Now I have some url in link_sp which I need in another class named RetrofitClient

RetrofitClient.java

// Getting value of link_sp here
String BASE_URL = MainActivity.getLink();
...
Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

Error:

Error when variable was empty as suggested by user cahyo

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.abc.abc/com.abc.remotegsmmodem.MainActivity}: java.lang.IllegalArgumentException: Expected URL scheme 'http' or 'https' but no colon was found

Even if I didn't get an error I am not confident about this method that I am using, please anyone what is a STANDARD WAY to get the value of a variable from ACTIVITY in JAVA CLASS. Thank You

fWd82
  • 840
  • 1
  • 13
  • 31
  • 2
    The error says `Expected URL scheme 'http' or 'https' but no colon was found` did you set your base url properly ? – cahyo Aug 03 '21 at 03:28
  • You were right, that time there were nothing in `SharedPreferences` I filled variable with correct `URL` and it worked. Thanks – fWd82 Aug 03 '21 at 13:57

2 Answers2

1

You don't access Activity variables in other classes. You either pass those values in (via the constructor or as method parameters), or you don't put those values in the Activity. For example here- the Activity shouldn't know the base url. There's no reason for it to. That information should be known by the RetrofitClient class, and nothing else. So you should put it in your RetrofitClient. If you want to be able to change it via shared preferences (I assume to switch between production and staging?), then the RetrofitClient class should be passed in an instance of either Context or SharedPreferences and it should control all of the logic about setting up the network. The Activity shouldn't be in charge of that.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • Thank You for your answer. My app let user save their `API URL` at first start via `EditText` that I save in `SharedPrefrences`. So every time user opens app, app already know `API URL` and call server with specified URL. – fWd82 Aug 02 '21 at 18:06
  • Dear @Gabe Sechan Yes you are right. I have fix my problem (not by passing value from Class to Activity) but tweaking around, I am still interested in getting to know if there is any workaround if anyone need in maybe in the future. – fWd82 Aug 02 '21 at 20:00
1

I will answer question myself because I want it to close but leave advice for future visitors.

Unexpectedly my code is working yes I am getting value from Activity in Java Class. But professionally this isn't the right way to pass values from Activity to class. Since Class is the one to decide what to do and what not to do as mentioned by Gabe Sechan

I required this for Retrofit since my Retrofit gets URL from Users every time they first install this app. Good way is to use following links:

Set dynamic base url using Retrofit 2.0 and Dagger 2

Using retrofit to get url from different relative paths

Instead of passing my URL to Retrofit from Activity as mentioned above in question I used, because Retrofit let me easily do that :

public interface Api {

    @GET()
    Call<List<Results>> getSmth(
          @Url String url,
          @Query("id")     int id,
          @Query("status") int status
// Remember when you are using @Url don't specify anything in @Get() and this @Url string will override BASE_URL if specified as explained in above links
     );
}

and inside MainActivity.java I used:

sp = getSharedPreferences("MySharedPref", MODE_PRIVATE);
link_sp  = sp.getString("link", "");
update_link = link_sp + "my_api.php?action=update";

...
...
...

Call<List<Results>> call = RetrofitClient.getInstance().getMyApi().getSmth(update_link, id, status);
call.enqueue(new Callback<List<Results>>() {
...
}

Hope this will help future readers since I really didn't knew Retrofit let me do that. I will vote for this question to get closed.

fWd82
  • 840
  • 1
  • 13
  • 31