Skip to content

Commit 9851adb

Browse files
author
Oriental Sensation
committed
Enable changing handler's operation mode in run-time.
The handler had a bug when switching from async to sync, and vice-versa. Because the handler variable was final, switching from async to sync would not free the retained memory. Also, and more importantly, if the handler was sync and then switched to async, a NPE would result because the handler was always null from before. This is now fixed.
1 parent 6077c6a commit 9851adb

File tree

2 files changed

+33
-21
lines changed

2 files changed

+33
-21
lines changed

library/src/main/java/com/loopj/android/http/AsyncHttpResponseHandler.java

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,10 @@ public abstract class AsyncHttpResponseHandler implements ResponseHandlerInterfa
9191

9292
protected static final int BUFFER_SIZE = 4096;
9393

94-
private final Handler handler;
9594
public static final String DEFAULT_CHARSET = "UTF-8";
9695
private String responseCharset = DEFAULT_CHARSET;
97-
private Boolean useSynchronousMode = false;
96+
private Handler handler;
97+
private boolean useSynchronousMode;
9898

9999
private URI requestURI = null;
100100
private Header[] requestHeaders = null;
@@ -142,6 +142,21 @@ public boolean getUseSynchronousMode() {
142142

143143
@Override
144144
public void setUseSynchronousMode(boolean value) {
145+
// Test that a looper has been prepared prior to setting asynchronous mode.
146+
if (value && null == Looper.myLooper()) {
147+
value = false;
148+
Log.i(LOG_TAG, "Current thread has not called Looper.prepare(). Forcing synchronous mode.");
149+
}
150+
151+
// If using asynchronous mode.
152+
if (value && handler == null) {
153+
// Create a handler on current thread to submit tasks
154+
handler = new ResponderHandler(this);
155+
} else if (!value && handler != null) {
156+
// TODO: Consider adding a flag to remove all queued messages.
157+
handler = null;
158+
}
159+
145160
useSynchronousMode = value;
146161
}
147162

@@ -163,19 +178,8 @@ public String getCharset() {
163178
* Creates a new AsyncHttpResponseHandler
164179
*/
165180
public AsyncHttpResponseHandler() {
166-
boolean missingLooper = null == Looper.myLooper();
167-
// Try to create handler
168-
if (!missingLooper)
169-
handler = new ResponderHandler(this);
170-
else {
171-
// There is no Looper on this thread so synchronous mode should be used.
172-
handler = null;
173-
setUseSynchronousMode(true);
174-
Log.i(LOG_TAG, "Current thread has not called Looper.prepare(). Forcing synchronous mode.");
175-
}
176-
177-
// Init Looper by calling postRunnable without an argument.
178-
postRunnable(null);
181+
// Use asynchronous mode by default.
182+
setUseSynchronousMode(true);
179183
}
180184

181185
/**
@@ -314,7 +318,7 @@ protected void handleMessage(Message message) {
314318
}
315319

316320
protected void sendMessage(Message msg) {
317-
if (getUseSynchronousMode()) {
321+
if (getUseSynchronousMode() || handler == null) {
318322
handleMessage(msg);
319323
} else if (!Thread.currentThread().isInterrupted()) { // do not send messages if request has been cancelled
320324
handler.sendMessage(msg);
@@ -328,9 +332,9 @@ protected void sendMessage(Message msg) {
328332
*/
329333
protected void postRunnable(Runnable runnable) {
330334
if (runnable != null) {
331-
if (getUseSynchronousMode()){
332-
// This response handler is synchronous, run on current thread
333-
runnable.run();
335+
if (getUseSynchronousMode() || handler == null) {
336+
// This response handler is synchronous, run on current thread
337+
runnable.run();
334338
} else {
335339
// Otherwise, run on provided handler
336340
handler.post(runnable);
@@ -346,7 +350,15 @@ protected void postRunnable(Runnable runnable) {
346350
* @return Message instance, should not be null
347351
*/
348352
protected Message obtainMessage(int responseMessageId, Object responseMessageData) {
349-
return Message.obtain(handler, responseMessageId, responseMessageData);
353+
Message msg;
354+
if (handler == null) {
355+
msg = Message.obtain();
356+
msg.what = responseMessageId;
357+
msg.obj = responseMessageData;
358+
} else {
359+
msg = Message.obtain(handler, responseMessageId, responseMessageData);
360+
}
361+
return msg;
350362
}
351363

352364
@Override

library/src/main/java/com/loopj/android/http/ResponseHandlerInterface.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public interface ResponseHandlerInterface {
104104
void setUseSynchronousMode(boolean useSynchronousMode);
105105

106106
/**
107-
* Can set, whether the handler should be asynchronous or synchronous
107+
* Returns whether the handler is asynchronous or synchronous
108108
*
109109
* @return boolean if the ResponseHandler is running in synchronous mode
110110
*/

0 commit comments

Comments
 (0)