简体   繁体   中英

How can I periodically run a service/thread in background even when the screen is locked?

I'm working on an app that can check web data every half an hour and I need to ensure it keeps running as long as the power is on. For now, the structure of my app is like this:

  1. main_activity:
    AlarmManager in onCreate()
  2. alarm_receiver:
    start_service acquire partial_wl for the service
  3. service:
    get network data using StrictMode pop activity_2 if the data is expected
  4. activity_2:
    vibration button to exit (activity_2.this.finish())

But in testing I find the service will stop(be killed) after the first 30 mins. In addition, if I start a thread for networking in service instead of using StrictMode, it will be killed in 5mins after the screen is locked.

Hope someone could give a suggestion for this. It's truly disturbing. Many thanks.

common service lives no metter what is happen with activity. if you want it start periodically check out mine service: https://bitbucket.org/kvrus/ocs-android/raw/036de7f0d3579b2a193bcb82309f7f82819508e6/app/src/main/java/koss/ru/oneclickrate/network/EcbEuropeService.java

/** * Loads exchange rates form network periodically * Returns results in broadcast message. * Created by koss on 19.02.16. * */ public class EcbEuropeService extends Service {

public static final String ECB_URL = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";
public static final int UPDATE_PERIOD = 30000;
public static final int UPDATE_TICK = 1000;

public static final String NOTIFICATION = "koss.ru.oneclickrate.receiver";
public static final String EXTRA_CURRENCIES_MAP = "extra_currencies_map";

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    getUrlData();
    return Service.START_NOT_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

public Cubes getUrlData() {
    (new AsyncTask<Object, Object, Cubes>() {
        Map<CurrencyType, BigDecimal> result = new EnumMap<CurrencyType, BigDecimal>(CurrencyType.class);

        @Override
        protected Cubes doInBackground(Object... params) {
            Cubes cubes = new Cubes();
            InputStream is = null;
            HttpURLConnection urlConnection = null;
            try {
                URL url = new URL(ECB_URL);
                urlConnection = (HttpURLConnection) url.openConnection();
                is = urlConnection.getInputStream();
                cubes = EcbEuropeResponseParser.parse(is);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if(urlConnection!=null) IOUtils.close(urlConnection);
                if(is!=null) IOUtils.closeQuietly(is);
                return cubes;
            }
        }

        @Override
        protected void onPostExecute(Cubes map) {
            super.onPostExecute(map);
            sendBroadcastMessage(map);
            startTimer();
        }
    }).execute();
    return null;
}

/**
 * Restarts timer
 * */
public void startTimer() {
    cdt.cancel();
    cdt.start();
}

CountDownTimer cdt = new CountDownTimer(UPDATE_PERIOD, UPDATE_TICK) {
    @Override
    public void onTick(long millisUntilFinished) {

    }

    public void onFinish() {
        getUrlData();
    }
};

private void sendBroadcastMessage(Cubes currenciesMap) {
    Intent intent = new Intent(NOTIFICATION);
    intent.putExtra(EXTRA_CURRENCIES_MAP, currenciesMap);
    sendBroadcast(intent);
}

I have changed a few things and it works well now.

1.As my phone is 4.4.2(api=19), alarmmanager.setrepeating is inexact. So I turn to use .setExact (new method of .set()) and reschedule the alarm at the end of AsyncTask(network) in Service.

2.Make wakelock instance global, acquiring it in AlarmReceiver and releasing at the end of the AsyncTask. I used to put .release() in onDestroy() which releases the lock before the task is done.

3.There is a setting about protected-background applications in my phone and I didn't turn it on. That can allow system kill the application and disable the alarm manager.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM