2

Please review steps 1 & 2 if approch is correct. Also, suggest how to code step 2.

Problem Statement:

1. Start a ongoing thread to capture status of the application.

Thread thread = new Thread() {
    public void run() {
        while (true) {
            try {
                checkStaus();
                Thread.sleep(TIMER); // 1 mins
            } catch (InterruptedException e) {
                Log.e("MyService", "local Thread error", e);
            }
        }
    }
};
thread.start();

2. When 10 mins has been passed, send the captured logs to server.

Pseudo:

a. Maintain counter until it reaches 600000 milliseconds (10 mins)

b. Start an async task to send captured logs to server.

c. After successful sending of file, reset counter; empty log file and continue capturing logs.

Thanks

adam black
  • 607
  • 5
  • 14

2 Answers2

0
  1. There's absolutely no way to end your thread. It will continue looping LONG after your Activity is killed. Since it's also an internal class, it will hold a reference to your dead Activity causing a pretty big memory leak.

    • To fix: Remove while(true) and replace it with a boolean like while(isRunning). Set isRunning to false in onDestroy().
  2. A better approach may be to use IntentService instead of AsyncTask. IntentService is a very handy tool that's meant for this kind of thing. You can set a timer to run every 10 minutes, then start the IntentService to send the log to the server. It will run in the background and you don't have to worry about it being dumped by the system or memory leaks if the user leaves the app.

The only thing you have to worry about is the file doesn't get deleted before sending. What you can do is right to a new file every time. So it would be something like this:

Write logs to `File1`
At ten minutes, start `IntentService`.  Pass the name of the file in the `Intent` used to start it`
Start writing logs to `File2`

In the IntentService

Get file name for file to send in the Intent
Send file to server
On completion, delete file
DeeV
  • 35,865
  • 9
  • 108
  • 95
  • Thanks for your quick response. I. I'm thinking of running this entire operation in an `IntentService`, thus it will not be connected to any activity, so do you think suggestion 1 is still required. II. As in suggestion 2 , then is it OK start an new IntentService inside another IntentService? – adam black Oct 25 '14 at 17:42
  • The thing about IntentService is they run in a queue. Meaning one won't start until one before it finishes. They are not intended to run for 10 minutes long. An IntentService would be the preferred way if you needed to be gathering statistics from within the Activity. If it's completely fine to gather them from a Service, then you may be better off just starting a Service and running a generic Thread from that. – DeeV Oct 25 '14 at 22:48
  • But as described [here](http://stackoverflow.com/a/15772151/4064208). I think it is the other way round. IntenetService can be used for longer ongoing tasks rather than service. Please suggest as now I'm confused. But for parallel IntentServices I agree with you. – adam black Oct 26 '14 at 06:07
  • You can absolutely use IntentService for long running operations, but it'll block the queue if you want to run more (you don't now, but may want to later). Now that I think about it though, I'm not sure if there is a queue for each IntentService class or if there's a single IntentService queue for the entire Application. – DeeV Oct 26 '14 at 17:10
0

Use a TimerTask, something like the following:

Timer timer = new Timer();
TimerTask task = new TimerTask() {
    public void run() {
        // ... stuff
        boolean run_again = ???  /// end infinite loop or not .. you should set this somewhere
        if (run_again)
           timer.schedule(this, 600000);
    }
}
timer.schedule(task, 600000); // or 0 if you want to run it right away first

syntax might be a bit off from memory

nikdeapen
  • 1,581
  • 3
  • 15
  • 27