我尝试(在Android应用程序中)使用单例模式将我的主线程与向服务器发出http请求的目标服务同步。我无法理解正确的实现,并想知道我是否可以在正确的方向上找到一些指示。
所以,这是来自主线程的http请求的示例用法:
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());
这是SyncManager的单例,我承认这是从我早期的一个主题的解决方案中找到的:Thread Synchronization with IntentService(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);
}
}
关于监听器的所有内容都来自原始解决方案(并且目前在代码中未使用),我并不真正理解如何使用它们,但我觉得这可能是纠正实现的关键。关于返回标志和响应的所有内容都是我的,它们目前无法正常工作。
以下是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;
}
摘要:
所以,您可能会从示例调用中注意到,我希望能够做的是进行HTTP调用,然后在返回该调用后,访问数据(现在我和#39;在Log.d函数中获得空指针异常,因为在http请求返回后可以填充&#39; respose&#39;变量之前调用该语句。因此,一旦服务启动,我想阻止启动它的线程,然后在服务停止运行后取消阻止它。在早期的帖子中作为答案给出的示例单例结构似乎很有希望,但我不知道如何实现包含的侦听器部分。相反,我试图在单个变量上设置 synchronized ,因此SyncManager代码的部分与侦听器无关,但是不起作用。寻找有关如何实现单例模式的更多见解,以实现我在目标服务进行http调用时阻止主线程的目标。
我意识到我的一些措辞可能看起来过于重复,但我非常努力地成为过去贬低的特定b / c。
答案 0 :(得分:2)
您不需要任何单身人士来实现您的目标。使用AsyncTask
,请参阅文档here。基本上你需要覆盖在后台线程上执行的doInBackground()
方法;在这里,您将实施HTTPRequest
投放。后台线程将一直等到它从服务器获得响应(或超时),并通过调用onPostExecute()
将结果提供给主线程,您可以在其中实现如何处理结果。