Question

I have noticed a problem on some devices where a crash occurs in an AsyncTask. It works without issue on my tablet and smartphone, but my friend had an issue on his device.

Here is an example of the body of one of my AsyncTasks:

protected String doInBackground(String... params) {
    String result = "";
    HttpClient httpclient = GlobalValues.getHttpClient();
    HttpPost httppost = new HttpPost(String.format(GlobalValues.getServiceUrl() + "%s", params[0]));

    try {
        HttpResponse response = httpclient.execute(httppost, GlobalValues.getLocalContext());
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream instream = entity.getContent();
            result = GlobalValues.convertStreamToString(instream);
            Log.i(params[0], params[0] + ": " + result);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
}

LOG:

FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
...
Caused by: java.lang.NullPointerException
...

The error occurs in the line:

HttpResponse response = httpclient.execute(httppost, GlobalValues.getLocalContext());

httppost contains the server url, which is set inside the method, with help from GlobalValues.getServiceUrl() and params[]. The session cookie is stored in an HttpContext, which is retrieved from GlobalValues.getLocalContext(), set when the application is first launched and shared by all of my AsyncTasks. I don't understand where a NullPointerException might be thrown.

I've looked at other questions/answers, but haven't found a solution.

  • The LocalContext is shared
  • The InputStream is closed in the HttpResponse response = httpclient.execute(httppost, GlobalValues.getLocalContext()).

Has anyone encountered this before &/ know what might be the problem?

EDIT:

Launcher Activity -

private DefaultHttpClient httpclient;
private HttpContext localContext;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    httpclient = new DefaultHttpClient();
    localContext = new BasicHttpContext();

    CookieStore cookieStore = new BasicCookieStore();
    localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

    GlobalValues.setHttpClient(httpclient);
    GlobalValues.setLocalContext(localContext);

GlobalValues -

protected static DefaultHttpClient httpclient;
protected static HttpContext localContext;

public static final DefaultHttpClient getHttpClient() {
    return httpclient;
}

public static final HttpContext getLocalContext() {
    return localContext;
}

public static final void setHttpClient(DefaultHttpClient httpclient) {
    GlobalValues.httpclient = httpclient;
}

public static final void setLocalContext(HttpContext localContext) {
    GlobalValues.localContext = localContext;
}

UPDATE: I've discovered that the issue only happens when someone tries to restore the application. I've stopped the application from crashing by adding "if(null) re-instantiate variable" in GlobalValues.getHttpClient() and GlobalValues.getLocalContext(). However, the session cookie stored in LocalContext is lost. Any ideas how to re-instantiate the values or the variables without loss of data?

Was it helpful?

Solution

The NullPointerException in that line means that httpclient has been null - which from your code points to GlobalValues.getHttpClient(), which reads from a static field.

You instanciate your static field in the onCreate method of another activity. This will not work, as android might kill your app and re-create only the visible activity. In that case, your initialization code is not called.


Quick Fix: Change your GlobalValues class to do initialization work:

protected static DefaultHttpClient httpclient = new DefaultHttpClient();

Your GlobalValues class seems a bit like you tried a "Singleton Pattern", see an answer about singleton patterns in general, and move all your construction code into the GlobalValues constructor. That way all your construction code is called before your static features are used.

OTHER TIPS

IS it possible that your GlobalValues is getting stepped on by another async process?

Also, not all Androids are the same. Your friend may have a phone from a manufacturer that implements AsyncTask differently enough to cause issues

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top