Phate
Phate

Reputation: 6612

Wait for a network chage in a service, in order to download updates

I have a service which periodically downloads some updates from a web site. Default period is long, about 10 mins and I do that with an AlarmManager which starts this service.

Network can be on or off, in case it's off service should download news as soon as network returns on, because interval is long and, in the worst case, you could have to wait 20 min till next update.

I made a network state broadcast receiver, and, with little code I made a NetworkListener interface:

public interface NetworkStateListener {
public void onNetworkOn();
public void onNetworkDown();
}

So my service has these 2 methods and can know when network goes on or off.

My idea is the following: in the onStart() method I spawn a new thread: if network is off thread waits, otherwise downloads. When onNetworkOn() is called I call a notify():

private boolean threadWaiting; //a flag so that I don't spawn multiple threads
public int onStartCommand(Intent intent, int flags, int startId) {
    if(!threadWaiting){//if already a thread waiting do nothing and exit
        Thread t = new Thread(new Runnable(){

            @Override
            public void run() {
                synchronized(binder){
                    while(!isNetworkOn())
                        try {
                            threadWaiting = true;
                            binder.wait();
                        }catch(InterruptedException ex){
                            ex.printStackTrace();
                        }
                }
                // blocks until network connection is available
               threadWaiting = false;
               //... operations ...

And this is onNetworkOn() method:

public void onNetworkOn() {
    synchronized(binder){
        binder.notify();
    }

is this the right way to proceed?

Upvotes: 0

Views: 96

Answers (2)

Phate
Phate

Reputation: 6612

Solved: I keep a boolean flag "missed update in my service":

boolean missedUpdate = false;

then in my onStartCommand:

if(isNetworkOn()){
    //do actual code
}else
    missedUpdate = true;

while in my on network on:

public void onNetworkOn(){
    if(missedUpdate){
       //download updated news
       // reset timer
       missedUpdate = false;
    }
}

Upvotes: 0

CommonsWare
CommonsWare

Reputation: 1006869

is this the right way to proceed?

IMHO, it is not ideal, as you are keeping a service around in memory. Plus, if your service is an IntentService, you will have leaked a thread and may never find out about the connectivity change.

I would have a BroadcastReceiver set up in the manifest for CONNECTIVITY_ACTION broadcasts, with that receiver initially disabled. If, when an alarm occurs, you find that you have no connectivity, enable that receiver. When the receiver receives the "we have a connection" broadcasts, have it call startService() to send a command to your service to go do the work, then have the receiver disable itself. This way, you do not need to keep the service running all of the time.

Upvotes: 2

Related Questions