-
Notifications
You must be signed in to change notification settings - Fork 4.1k
JsonHttpResponseHandler throws NullPointerException when run in loop #397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Update: my workaround for now is to replicate the JsonHttpResponseHandler's parseResponse method as a static method in the AppRestClient class, then call it and cast its response accordingly. Example, assumes existence of public static Object parseResponse(String r) on AppRestClient: @Override
public void onSuccess(String res) {
Log.d("logger", "succ - " + res);
JSONObject jsonResponse = (JSONObject) AppRestClient.parseResponse(res);
Log.d("logger", jsonResponse.toString();
} |
I don't even see the line 412 in AsyncHttpResponseHandler, what version of library do you use? protected void postRunnable(Runnable runnable) {
// Adding handler != null should avoid NPE but is not general solution
if (runnable != null /*&& handler != null*/) {
handler.post(runnable);
}
} |
No idea what's detected as null. Using 1.4.4, the corresponding lines are: JsonHttpResponseHandler (153==first line): postRunnable(new Runnable() {
@Override
public void run() {
if (jsonResponse instanceof JSONObject) {
onSuccess(statusCode, headers, (JSONObject) jsonResponse);
} else if (jsonResponse instanceof JSONArray) {
onSuccess(statusCode, headers, (JSONArray) jsonResponse);
} else if (jsonResponse instanceof String) {
onSuccess(statusCode, headers, (String) jsonResponse);
} else {
onFailure(new JSONException("Unexpected type " + jsonResponse.getClass().getName()), (JSONObject) null);
}
}
}); AsyncHttpResponseHandler (412==handler.post): protected void postRunnable(Runnable r) {
if (r != null) {
handler.post(r);
}
} Looks like JsonHttpResponseHandler is having trouble with the super() init calls bubbling up through TextHttpResponseHandler, as Async declares handler on init; since Async works itself, I'd imagine it isn't a case of Looper.myLooper() returning null. Any advice re: submitting a patch? Java is far from my primary language, though I'd be happy to help if possible. |
Looks like handler got's released or nulled. |
Hi, I have encountered the same issue and found out handler was never created in the beginning. because |
Hi, I have encountered the same issue . Using 1.4.4 , How to fix it . |
This issue occurred because I made the call on worker thread. |
I use Handler sendMessage do some request . OK |
same issue here, how did you fix it? even if using runonuithread I still get this error. |
I send a message. In handler do your request. 发自 Windows 邮件 发件人: lucasjotab3 same issue here, how did you fix it? — |
Why you using in a workthread ? I use workthread do complte send a message return mainthread do request . 发自 Windows 邮件 发件人: nujabes8 This issue occurred because I made the call on worker thread. — |
I'm not sure if I got it, please take a look at my code below: this is where I make the request, inside some fragment's onCreateView... I'm not using asynctask or worker threads so far
AppAPI.get is a static method from a helper class I use to organize the requests:
when debugging, I find myself inside this Looper.java loop() function (a for loop at line 123). Somewhere inside it my app crashes... When debugging it seemed to be inside a infinite loop, though... log: if I try this (whith donwloadJson() being the method that makes the request) |
I have encountered the same error:
I suspect that this is some kind of a RaceCondition that occurs in JsonHttpResponseHandler, since I'm not running "AppRestClient.get(...)" in a loop. Possibly the "AppRestClient.get(...)" call needs to be done on the UI thread to avoid problems (and if it is a race-condition the other response handlers could have the same disease, but no symptoms). Unfortunately the line numbers are off to investigate by just looking at the source (there is no line 412 in https://github.com/loopj/android-async-http/blob/master/library/src/main/java/com/loopj/android/http/AsyncHttpResponseHandler.java - can we thank ProGuard for this or is there something strange going on?) |
Ran into this issue myself and here's what I've come up with: The line numbers correlate with 375c4cb. As stated above in this thread, it looks like A primary condition for this appears to be creating an asynchronous call from a thread that does not have it's own looper. This will prevent For a shitty workaround, you can extend your preferred @Override
protected void postRunnable(Runnable r) {
new Thread(r).run();
} This will NOT run your calls on the same thread it originated from, so I would advise finding another solution if you need to run your code on the UI thread. Additionally, this will require you to ensure that any code which requires a looper to call A better workaround would almost certainly be something like: @Override
protected void postRunnable(Runnable r) {
boolean hasLooper = true;
if (Looper.myLooper() == null) {
Looper.prepare();
hasLooper = false;
}
Handler handler = new AsyncHttpResponseHandler.ResponderHandler(this);
handler.post(r);
if (!hasLooper)
Looper.loop();
} but this would require modification of the library itself, specifically the addition of a |
Thanks for the input dambrisco After inspecting my own code I think that i have managed to call AppRestClient.get(...) on a thread without a Looper (there is a code path from a timer task). I have added the following code in a strategic place:
If it fires and I get the exception, I think that the problem has been verified. My solution will then be to ensure that the data load code is run on the UI thread, as is the case for the majority of the calls. I will report back when there are results (I only get the problem intermittently, probably when timer triggers and i have to realod data) |
After changing my code to trigger the timeout consistently, I could reproduce the error, and indeed, the timer thread did not have a looper. Wrapping the call to AppRestClient.get(...) in a runOnUITread:
did remove the exception. I think that the constructor in AsyncHttpResponseHandler.java:168 should be amended like this:
If AsyncHttpClient must run on the UI thread, check and throw as follows:
If it is OK not to run on the UI thread and it is OK to add an looper implicitly, the constructor code could be changed as follows:
Since I do not know which precondition that applies, I hope one of the maintainers could take a look at this and make a wise decision. |
I'm also having issues related to - possibly - weakreference. In my case i do .get with an instance of JsonHttpResponseHandler. The request starts as my onStart method gets called. then, in some rare cases, i don't get any other callback called: no onSuccess, no onFailure, no onFinish. This bug happes only when i launch the my app and android takes a bit of time to render it. I believe some memory stuff needs to get cleared and the weakreference gets lost. for now I fixed it by using an new Handler().postDelayed(new Runnable(){}, 500) but this is a workaround. I'm not expert of using WeakReference but what is the mean of using it if in certain conditions the request gets dropped in the middle of nowhere? |
@dambrisco I like your work on this case, using custom Looper if the library is not used from thread using one. I can try to implement it, or could provide a pull request, I'll see what will be done earlier. |
@anulman @Osram-Lux @dambrisco @lucasjotab3 please test provided fix, test against a3eb053 please. Possibly close this issue, if the latest master code is solution, and can be merged into next version of library. |
# By mareksebera # Via mareksebera * 'master' of https://github.com/loopj/android-async-http: Refactoring gone wrong, flipped condition android-async-http#397 Possibility to use library on non-UI thread (calling Looper.prepare) android-async-http#397 Unnecessary casting Throwing exception to fill expectations Removed hardcoded strings Fixed SDK targeting
@smarek New fix appears to be working correctly. I'd consider this issue closed with your next release. |
I may have pre-emptively stated that the fix was working correctly, at least in all contexts. There appears to be an issue with the runnable never actually running under certain conditions. I'm still working out what exactly the reason is, but given that using my I'll open a new issue when I have some more time as it's not directly related to this issue, but I wanted to make anyone interested aware that this is a known problem as of a3eb053. |
Shouldn't the looper be quitted eventually? I'm ending up with a few Running threads but I'm not figuring out how to quit the looper… Edit: Well, creating a new instance of AsyncHttpResponseHandler on a thread that's not the UI thread makes the constructor not return because of the looper. |
@dambrisco thanks, I'll be waiting to hear from you, I'm also trying to simulate the test case where the issue happens. @carlosefonseca can you add some code and start a new issue please? Thanks |
I am encountering this issue. I am using the loopj library in the network. Can someone help on pointing me in the direction for fixing this? I have an object Client that exposes a method that then fires the request. The handler is a JsonHttpResponseHandler that processes the request. The client is triggered in the runOnUIThread. Thanks! |
I had the same issue with JsonResponseHandler, works fine with AsyncHttpResponseHandler though |
Looks like this one is still alive. |
I'm hitting the same issue as well with version 1.4.4 lib bersion via gradle.. Any update? |
The milestone is with version 1.4.5. |
印象笔记无法提交笔记,原因如下: 本月帐户上传流量已经达到上限。 原消息详情: 为了防止邮件过多,接下来的360分钟内,你将不会收到报错回复。 升级到印象笔记高级帐户,可以发送的邮件数量将从50封提升到200封。
|
JsonHttpResponseHandler is throwing a NullPointerException when it is run in a loop. The standard AsyncHttpResponseHandler does not.
JsonHttpResponseHandler code:
Log output:
AsyncHttpResponseHandler code:
Log output:
The text was updated successfully, but these errors were encountered: