2

I am starting a thread from an android service that constantly uploads a file using a tcp connection to a server at constant intervals. The thread has a while(true) loop that performs this. The operations get performed for sometime but then it stops. I tried using the adb logcat to debug and saw certain messages I printed inside the thread for sometime only. After that they also stopped. Further when I stopped the service I got a NullPointerException since in the onDestroy() method of the service I had used the thread object.

Does the thread get killed and not run as long as the service runs? Do I need to do this while(true) operation in onStart() of service class itself and not spawn a new thread?

Any solution provided will be of great help.

Code is as follows (partly based on this answer by kuester2000):

    public void run() 
    {           
        Log.d("TAG","Starting Thread");         
        String data = "";   
        updateServer();
        while(flag)
        {                   
            String path = extStorageDirectory + "/" + appFolder + "/" + "SAT_pingLog_" + Long.toString(System.currentTimeMillis()) + ".txt";
            createFile(path);
            int count = 0;
            while(flag && count < 32768)
            {                               
                data = "";          
                String result = Long.toString(getLatency(url));                                     
                data = Long.toString(System.currentTimeMillis()) + " " + gps[0] + " " + gps[1] + " " + strength + " " + result;
                Log.d("DEBUGGING",data);
                writeToLog(path,data);
                try 
                {
                    Thread.sleep(sleepTime);
                } 
                catch (InterruptedException e) 
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                count++;
            }
            updateServer();
        }           
    }public long getLatency(String Url)
    {
        long startTime = 0, endTime = 0, latency = 0;                   
        try 
        {
            HttpParams httpParameters = new BasicHttpParams();
            // Set the timeout in milliseconds until a connection is established.
            // The default value is zero, that means the timeout is not used. 
            int timeoutConnection = 10000;
            HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
            // Set the default socket timeout (SO_TIMEOUT) 
            // in milliseconds which is the timeout for waiting for data.
            int timeoutSocket = 10000;
            HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
            DefaultHttpClient httpclient = new DefaultHttpClient(httpParameters);
            HttpHead httphead = new HttpHead(Url);
            //HttpParams httpParameters = new BasicHttpParams();                
            //HttpConnectionParams.setConnectionTimeout(httpParameters, 5000);
            //HttpConnectionParams.setSoTimeout(httpParameters, 5000);
            //HttpClient httpClient = new DefaultHttpClient(httpParameters);
            //request.setURI(new URI("http://www.google.com"));
            System.out.println("Executing request " + httphead.getURI());
            Log.d("DEBUGGING","STARTING EXECUTE");
            startTime = System.currentTimeMillis();             
            HttpResponse response = httpclient.execute(httphead);
            endTime = System.currentTimeMillis();
            Log.d("DEBUGGING","ENDING EXECUTE");
            int status = response.getStatusLine().getStatusCode();
            if (status == HttpStatus.SC_OK)                                
                latency = endTime - startTime;                                      
            else
                latency = 0;
        } 
        catch(Exception e)
        {
            Log.d("DEBUGGING","EXCEPTION CAUGHT");
            e.printStackTrace();
        }   
        Log.d("DEBUGGING","LATENCY:"+Long.toString(latency));
        return latency;
    }       
}
Ryan M
  • 18,333
  • 31
  • 67
  • 74

1 Answers1

3

Does the thread get killed and not run as long as the service runs?

Android components are oblivious to threads they did not create. So while IntentService will deal with the thread it created for the use of onHandleIntent(), a regular Service will pay no attention to any threads you fork yourself.

Once a service is destroyed, any threads it leaks will continue to run, until such time as Android terminates the process.

If your threads are stopping unexpectedly, that has nothing to do with Service -- again, Service knows nothing of threads that you fork yourself. Make sure that you are not silently eating exceptions by having empty catch blocks, as my guess is that something is raising an exception, causing you to exit your loop, but that you aren't logging it for some reason.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Will try analysing exception messages. What is your suggestion? Is running the loop in the service's onStart() a good idea? – user1761399 Oct 20 '12 at 12:19
  • @user1761399: "Is running the loop in the service's onStart() a good idea? " -- absolutely not. `onStart()` is called on the main application thread. Android will nuke your service from orbit within a few seconds if you tie up the main application thread that way. – CommonsWare Oct 20 '12 at 13:07
  • I have added the code. Variables and functions are in the same class where exceptions are handled in those codes. When can this while(loop) end unless flag is false? – user1761399 Oct 20 '12 at 14:11
  • @user1761399: It can crash anywhere outside of your `try`/`catch` block. – CommonsWare Oct 20 '12 at 17:32
  • As far as what I could debug I found that I don't get any further logcat messsages after a STARTING EXECUTE for a particular call to getLatency (Code attached to question). What can be a probable reason? – user1761399 Oct 21 '12 at 03:25
  • @user1761399: No clue, sorry. – CommonsWare Oct 21 '12 at 10:59
  • Actually the thing is what I need to do is very simple. Just ping a site at constant intervals and get the time it takes for the same. I tried using thread but it failed. I tried using Timer.schedule but that too stops after sometime. The logcat shows the service onCreate() method as the last method called after which the entire thing stops working. when all does the oncreate() and onstart() methods of a service get called and is not oncreate() always followed by call to onStart()? Can you suggest any other alternative to accomplish what I intend to do? – user1761399 Oct 21 '12 at 12:24
  • @user1761399: How long are you trying to do this for? What is your polling frequency? – CommonsWare Oct 21 '12 at 12:26
  • I am doing it every minute. like - timer.schedule(pingTask, 1000L, 60 * 1000L); or in case of thread I just sleep for 1 minute and then repeat. – user1761399 Oct 21 '12 at 12:36
  • @user1761399: How long are you trying to do this for? While your application is in the foreground? When the user manually starts and stops this polling? Or something else? – CommonsWare Oct 21 '12 at 12:38
  • The application just starts a service specifying the frequency and url to ping. Then the service creates this thread and does it per minute. The user can also later open the app and stop the service. Basically everything is being done by the service and I want it to run always which is not happening. – user1761399 Oct 21 '12 at 12:42
  • @user1761399: You can try switching to `AlarmManager` and an `IntentService`, perhaps [my `WakefulIntentService`](https://github.com/commonsguy/cwac-wakeful). However, please allow the user to control the polling period. Once a minute is rather frequent, and users may not appreciate the battery drain. – CommonsWare Oct 21 '12 at 12:46
  • Is'nt there any other simpler method? – user1761399 Oct 21 '12 at 13:03