I'm attempting to (In an android app) use a singleton pattern to synchronize my main thread with an intent service that makes http requests to a server. I'm having trouble understanding the proper implementation and was wondering if I might get a few pointers in the right direction.
SO, here is an example usage of the http request from the main thread:
Intent intent = new Intent(getActivity(), ClientService.class);
intent.putExtra(ClientService.REQUEST, ClientService.CLIENT_LIST_REQ);
SyncManager syncManager = SyncManager.getInstance(getActivity());
syncManager.submitHttpRequest(intent);
Log.d(TAG, syncManager.getResponse());
Here is the SyncManager singleton, which I admittedly took from a solution from an earlier topic of mine found here: Thread Synchronization with IntentService (solution by Vladimir Lichonos).
public class SyncManager {
private static SyncManager instance;
private Object Lock;
private boolean hasReturned;
private String response;
public Context mContext;
LinkedList<OnCompletionListener> mListeners;
private SyncManager(Context c){
mContext = c;
mListeners = new LinkedList<OnCompletionListener>();
hasReturned = false;
}
public static SyncManager getInstance(Context c) {
if(instance == null){
synchronized (SyncManager.class){
if(instance == null){
instance = new SyncManager(c.getApplicationContext());
}
}
}
return instance;
}
//to be called by the activity/fragment
public void submitHttpRequest(Intent intent){
mContext.startService(intent);
}
public boolean checkHasReturned(){
synchronized(Lock){
return hasReturned;
}
}
public void setReturnFlag(){
synchronized(Lock){
hasReturned = true;
}
}
public void resetReturnFlag(){
synchronized(Lock){
hasReturned = false;
}
}
public void setResponse(String response){
synchronized(Lock){
this.response = response;
}
}
public String getResponse(){
synchronized(Lock){
return response;
}
}
public void addListener(OnCompletionListener listener){
synchronized(mListeners){
mListeners.add(listener);
}
}
public void removeListener(OnCompletionListener listener){
synchronized(mListeners){
mListeners.remove(listener);
}
}
//to be called by the service
public void HttpRequestComplete(){
synchronized(mListeners){
for (OnCompletionListener listener : mListeners){
listener.onCompleted(this);
}
}
}
public static interface OnCompletionListener{
public void onCompleted(SyncManager instance);
}
}
All the stuff about listeners is from the original solution (and is currently unused in the code), and I didn't really understand how to use them, but I feel like that might be the key to correct implementation. All the stuff about Return flags and responses are mine, and they currently do not work.
Here is the significant part of the ClientService:
protected void onHandleIntent(Intent intent) {
SyncManager syncManager = SyncManager.getInstance(getApplicationContext());
Log.d(TAG, "entered onHandleIntent");
int rqst = intent.getIntExtra(REQUEST, DEFAULT_REQ);
Log.d(TAG, ""+rqst);
String response = "";
switch(rqst){
case ABOUT_REQ:
response = getAbout();
break;
case VER_DATA_REQ:
response = getVerificationData("douglas_adams_uri");
break;
case CLIENT_LIST_REQ:
response = getClientList();
break;
}
syncManager.setResponse(response);
syncManager.setReturnFlag();
return;
}
In Summary:
So, you might notice from the sample call, that what I want to be able to do is to make an HTTP call and then after that call is returned, access the data (right now i'm getting a null pointer exception in the Log.d function because that statement is being called before the 'respose' variable can be populated by the http request return). Thus, once the service is started, I want to block the thread that started it and then unblock it once the service has stopped running. The sample singleton structure given as an answer to me in an earlier thread seems promising, but I don't know how to implement the listener parts that are included. Instead, i tried to just set synchronized on a single variable, hence the parts of the SyncManager code that are not about listeners, but that does not work. Looking for more insight on how I might implement the singleton pattern to accomplish my goal of blocking the main thread while the http call is made by the intent service.
I realize some of my wording might seem overly repetitive, but i'm trying very hard to be specific b/c of past downvoting.