我正在尝试(在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单例,我承认它是从我在这里找到的一个早期主题的解决方案中获得的:线程同步与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调用,然后在该调用返回之后,访问数据(现在我在日志中得到空指针异常)。D函数,因为该语句在HTTP请求返回填充' response '变量之前被调用)。因此,一旦服务启动,我想要阻塞启动它的线程,然后在服务停止运行后解除对它的阻塞。在前面的一个线程中,作为对我的回答给出的样例单例结构似乎很有希望,但我不知道如何实现包含的侦听器部分。相反,我试图在单个变量上设置同步,因此SyncManager代码的部分与侦听器无关,但这不起作用。寻找更多关于我如何实现单例模式来完成我的目标,即在http调用由intent服务进行时阻塞主线程。
我意识到我的一些措辞可能看起来过于重复,但我正在非常努力地具体说明过去的不赞成。
您不需要任何单例来实现您的目标。使用AsyncTask
,请参阅此处的文档。基本上你需要重写doInBackground()
方法,它是在后台线程中执行的;在这里你将实现HTTPRequest
的交付。后台线程将等待,直到它从服务器获得响应(或超时),并将通过调用onPostExecute()
将结果提供给主线程,在那里您可以实现如何处理结果。