For context, I am making an app which communicates with TCP server hosted currently on my local pc. I am using SSLSocket
for secure connection. All communications are ok. I have made a special class for handling all communications with the server. I know that I have to do it on background thread so I have already initialized ExecutorService and Handler in the class. Before explaining the problem, let me show the code of the class and when I call it.
Communication Class :-
private ExecutorService executor = Executors.newSingleThreadExecutor();
private Handler handler = new Handler(Looper.getMainLooper());
public String genAuthToken(String userName, String passwd) throws Exception{
if(!connected)return null;
JSONObject json = new JSONObject();
json.put("func","genAuthToken");
json.put("userName",userName);
json.put("passwd",passwd);
JSONObject finalJSON = json;
final String[] reply = {""};
pw.println(finalJSON);
reply[0] = scan.nextLine();
json = new JSONObject(reply[0]);
if((int) json.get("code") == 200){
this.authToken = json.get("authToken").toString();
return (String) json.get("authToken");
}
return String.valueOf((int) json.get("code"));
}
MainActivity.java :-
LedGo client = new LedGo();
boolean connected = client.connect("192.168.1.4",1304,cf,()->{},()->{Snackbar.make(view,"Couldn't connect to server",Snackbar.LENGTH_SHORT).setAnchorView(R.id.fab).show();});
String authToken = client.genAuthToken("userName","passwd",true,()->{},()->{});
Now the problem is that I want to get authToken
in MainActivity.java
. I know that I cannot get it like I wrote above but I want to know how can I extract some data from ExecutorService
. I thought of one option of making a public variable which could be accessed by MainActivity
but that is not practical because app would be sending many requests from different thread at same time. In short, I want to know how to get variable from ExecutorService.execute()
in MainActivity.java
. If anything is not clear please tell me, I would really appreciate the help.
How to get some values from ExecutorService.execute() function in Android Development, Java
Simply make it event driven just like many things done in Android framework.
It is clean, reliable and nonblocking.
To implement, create an interface called AuthTokenListener
:
interface AuthTokenListener {
onAuthTokenReady(String authToken)
}
Add a AuthTokenListener
parameter to the genAuthToken
method and invoke it when the token is ready. See the following snippet:
Communication class:
private ExecutorService executor = Executors.newSingleThreadExecutor();
private Handler handler = new Handler(Looper.getMainLooper());
public void genAuthToken(String userName, String passwd, AuthTokenListener listener) throws Exception{
if(!connected)return null;
JSONObject json = new JSONObject();
json.put("func","genAuthToken");
json.put("userName",userName);
json.put("passwd",passwd);
JSONObject finalJSON = json;
final String[] reply = {""};
pw.println(finalJSON);
reply[0] = scan.nextLine();
json = new JSONObject(reply[0]);
if((int) json.get("code") == 200){
this.authToken = json.get("authToken").toString();
return (String) json.get("authToken");
}
// Looks like your token is ready to publish here
// Then invoke the onAuthTokenReady method of the listener so that
// it gets processed in the main activity
listener.onAuthTokenReady(String.valueOf((int) json.get("code")));
}
Finally in your main activity you should implement the AuthTokenListener
either making the activity class implement it or anonymly (in place) implementing:
class MainActivity extends AppCompatActivity implements AuthTokenListener {
@Override
void onAuthTokenReady(String authToken) {
// Process the authToken here
}
// Somewhere in your main MainActivity's method
private void mainActivityMethodYouCreateLedGoClient() {
LedGo client = new LedGo();
boolean connected = client.connect("192.168.1.4",1304,cf,()->{},()->{Snackbar.make(view,"Couldn't connect to server",Snackbar.LENGTH_SHORT).setAnchorView(R.id.fab).show();});
client.genAuthToken("userName","passwd", this);
}
}
class MainActivity extends AppCompatActivity implements AuthTokenListener {
// Somewhere in your main MainActivity's method
private void mainActivityMethodYouCreateLedGoClient() {
LedGo client = new LedGo();
boolean connected = client.connect("192.168.1.4",1304,cf,()->{},()->{Snackbar.make(view,"Couldn't connect to server",Snackbar.LENGTH_SHORT).setAnchorView(R.id.fab).show();});
client.genAuthToken("userName","passwd", new AuthTokenListener {
@Override
void onAuthTokenReady(String authToken) {
// Process the authToken here
}
});
}
}
However I did not see you used the executor
anywhere in Communication
class.
Also I'd like to remind you that if you invoke the listener method from a background thread, and you wanna modify some UI element then you should do it in main thread.