How to remove stack overflow on call to Ljava/lang/VMThread from following code for android

StackOverflow https://stackoverflow.com/questions/21926475

  •  14-10-2022
  •  | 
  •  

Вопрос

I am developing android data upload app and calling Http Get request to upload data. I am calling request on successful result of previous request. There are 300 to 500 records so the request function will get called 300 to 500 times. Please look at the data uploading function. All these functions are running in AsyncTask in doInBackground function

public class CheckKswaAccessToken {

int counter = 0;
CampListView camps;
HttpClient httpclient;

public CheckKswaAccessToken(CampListView view) {
    camps = view;
    new TheTask().execute();
}
class TheTask extends AsyncTask<Void,Void,Void>
{
    @Override
    protected Void doInBackground(Void... params) {
        getAccessToken();
        return null; 
    }
}

public HttpClient getNewHttpClient() {
    try {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);

        SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", sf, 443));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        return new DefaultHttpClient(ccm, params);
    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}
private void getAccessToken() {
    httpclient = getNewHttpClient();
    URI oops;
    try {
        oops = new URI("http://pathtoserver/oauth/token");
        HttpPost httppost =  new HttpPost(oops);
        List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>();
        nameValuePair.add(new BasicNameValuePair("client_id", "ca732a6508d6ec8a1fdca"));
        nameValuePair.add(new BasicNameValuePair("client_secret", "22107f85d4cc80e91fcd73"));
        try {
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePair));
            HttpResponse response = httpclient.execute(httppost);

            BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            StringBuffer result = new StringBuffer();
            String line = "";
            while ((line = rd.readLine()) != null) {
                result.append(line);
            }
            String resultStr = result.toString();
            if(resultStr != null)
            {
                try {
                    JSONObject jObj = new JSONObject(resultStr);
                    uploadData(jObj.getString("access_token"));
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } catch (URISyntaxException e1) {
        e1.printStackTrace();
    }

}
private void uploadData(String token)
{
    counter++;
    if(counter < 300)
    {
        testRequest(token);
    }
}
private void testRequest(String token)
{
    URI path;
    try {
        path = new URI("http://pathtoserver/api/schools");
        HttpGet httpget = new HttpGet(path);
        httpget.addHeader("Authorization", "Token token=\"" + token + "\"");
        try {

            HttpResponse response = httpclient.execute(httpget);
            BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            StringBuffer result = new StringBuffer();
            String line = "";
            while ((line = rd.readLine()) != null) {
                result.append(line);
            }
            uploadData(token);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } catch (URISyntaxException e1) {
        e1.printStackTrace();
    }
}

} I am getting following exception after 127 successful HTTP get requests

02-21 10:54:37.419: I/dalvikvm(804): threadid=15: stack overflow on call to Ljava/lang/VMThread;.currentThread:L
02-21 10:54:37.419: I/dalvikvm(804):   method requires 0+20+0=20 bytes, fp is 0x4a474300 (0 left)
02-21 10:54:37.419: I/dalvikvm(804):   expanding stack end (0x4a474300 to 0x4a474000)
02-21 10:54:37.819: I/dalvikvm(804): Shrank stack (to 0x4a474300, curFrame is 0x4a477f20)
02-21 10:58:34.482: W/dalvikvm(804): threadid=15: thread exiting with uncaught exception (group=0x40a71930)
02-21 10:58:35.539: E/AndroidRuntime(804): FATAL EXCEPTION: AsyncTask #3
02-21 10:58:35.539: E/AndroidRuntime(804): java.lang.RuntimeException: An error occured while executing doInBackground()
02-21 10:58:35.539: E/AndroidRuntime(804):  at android.os.AsyncTask$3.done(AsyncTask.java:299)
02-21 10:58:35.539: E/AndroidRuntime(804):  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
02-21 10:58:35.539: E/AndroidRuntime(804):  at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
02-21 10:58:35.539: E/AndroidRuntime(804):  at java.util.concurrent.FutureTask.run(FutureTask.java:239)
02-21 10:58:35.539: E/AndroidRuntime(804):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
02-21 10:58:35.539: E/AndroidRuntime(804):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
02-21 10:58:35.539: E/AndroidRuntime(804):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
02-21 10:58:35.539: E/AndroidRuntime(804):  at java.lang.Thread.run(Thread.java:856)
02-21 10:58:35.539: E/AndroidRuntime(804): Caused by: java.lang.StackOverflowError
02-21 10:58:35.539: E/AndroidRuntime(804):  at java.lang.Thread.currentThread(Thread.java:476)
02-21 10:58:35.539: E/AndroidRuntime(804):  at java.lang.ThreadLocal.get(ThreadLocal.java:53)
02-21 10:58:35.539: E/AndroidRuntime(804):  at dalvik.system.BlockGuard.getThreadPolicy(BlockGuard.java:140)
02-21 10:58:35.539: E/AndroidRuntime(804):  at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163)
02-21 10:58:35.539: E/AndroidRuntime(804):  at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
02-21 10:58:35.539: E/AndroidRuntime(804):  at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
02-21 10:58:35.539: E/AndroidRuntime(804):  at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
02-21 10:58:35.539: E/AndroidRuntime(804):  at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
02-21 10:58:35.539: E/AndroidRuntime(804):  at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
02-21 10:58:35.539: E/AndroidRuntime(804):  at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:191)
02-21 10:58:35.539: E/AndroidRuntime(804):  at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:82)
02-21 10:58:35.539: E/AndroidRuntime(804):  at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:174)
02-21 10:58:35.539: E/AndroidRuntime(804):  at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:180)
02-21 10:58:35.539: E/AndroidRuntime(804):  at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:235)
02-21 10:58:35.539: E/AndroidRuntime(804):  at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:259)
02-21 10:58:35.539: E/AndroidRuntime(804):  at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:279)
02-21 10:58:35.539: E/AndroidRuntime(804):  at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:121)
02-21 10:58:35.539: E/AndroidRuntime(804):  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:428)
02-21 10:58:35.539: E/AndroidRuntime(804):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
02-21 10:58:35.539: E/AndroidRuntime(804):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
02-21 10:58:35.539: E/AndroidRuntime(804):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
02-21 10:58:35.539: E/AndroidRuntime(804):  at com.chronos.kswa01.CheckKswaAccessToken.testRequest(CheckKswaAccessToken.java:176)
02-21 10:58:35.539: E/AndroidRuntime(804):  at com.chronos.kswa01.CheckKswaAccessToken.uploadData
Это было полезно?

Решение

You simply need to remove the uploadData(token) call in testRequest(String token). When testRequest completes, it get backs to your for loop anyway (in uploadData), which will call testRequest again on next iteration.

Also, if you want to stop the iteration in case one upload failed, you probably want to avoid catching all exception in testRequest or at least make it return a boolean that would indicates if everything was ok.

private void uploadData(String token)
{

    for (int i = O; i< 300 ; ++i)
    {
       if (!testRequest(token)) {
          // To some logging
          break;
       }
    }
}

private void testRequest(String token)
{
    Log.d("result:", token);
    //HttpClient httpclient = getNewHttpClient();
    URI path;
    try {
       // UPLOAD CODE 
        return true;

        } catch (UnsupportedEncodingException e) {
           // all your catch blocks

        }
    return false; 
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top