How to execute background task when Android app is closed / set to background?

后端 未结 4 459
再見小時候
再見小時候 2020-12-03 01:47

My Android 4+ app is connected to a custom web service that is used to sync data every few minutes. To make sure, that the online data is always up to date, I want to trigge

相关标签:
4条回答
  • 2020-12-03 02:06

    You can use services for what you want to achieve. A service will keep on running in the background even when the activity component has been destroyed, provided you have not invoked stopService(..) or stopSelf() methods.

    In the service you can make an Async network call, preferably using retrofit, and then you can update you local storage like Sqlite DB with the latest data fetched from your web service.

    Here is the official link, you can just use an unbounded service for what you want to achieve.

    0 讨论(0)
  • 2020-12-03 02:08

    The following code will help you to post your contents when your app is closed or in the background:

    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.Handler;
    import android.os.IBinder;
    import android.widget.Toast;
    
    public class SendDataService extends Service {
        private final LocalBinder mBinder = new LocalBinder();
        protected Handler handler;
        protected Toast mToast;
     
        public class LocalBinder extends Binder {
            public SendDataService getService() {
                return SendDataService .this;
            }
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return mBinder;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
    
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            handler = new Handler();
            handler.post(new Runnable() {
                @Override
                public void run() { 
    
    // write your code to post content on server
                }
            });
            return android.app.Service.START_STICKY;
        }
    
    }
    

    More explanation of my code is:

    Service runs in the background even if your application is in the background, but remember, it always runs on the main thread, because of which I created a separate thread to perform your background operations.

    Service is started as a sticky one, as even if because of any reason your service got destroyed in the background it will automatically get restarted.

    More details can be found here: https://developer.android.com/guide/components/services.html

    And to check if your app is in the foreground/background, the following code will help:

      private boolean isAppOnForeground(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        if (appProcesses == null) {
          return false;
        }
        final String packageName = context.getPackageName();
        for (RunningAppProcessInfo appProcess : appProcesses) {
          if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
            return true;
          }
        }
        return false;
      }
    }
    
    // Use like this:
    boolean foregroud = new ForegroundCheckTask().execute(context).get();
    

    Happy Coding!!!!

    0 讨论(0)
  • 2020-12-03 02:08

    The accepted answer is not correct.

    Unfortunately, the author believes that posting a new Runnable task to the Handler() creates a separate thread - "I created a separate thread to perform your background operations" :

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        handler = new Handler();
        handler.post(new Runnable() {
            @Override
            public void run() { 
               // write your code to post content on server
            }
        });
        return android.app.Service.START_STICKY;
    }
    

    onStartCommand() callback is always called on the main thread, and the new Handler() is attached to the current thread (which is "main"). So the Runnable task is posted at the end of main thread queue.

    To fix the issue and execute the Runnable in a really separate thread you can use AsyncTask as the simplest solution:

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                // ...
            }
        });
        return android.app.Service.START_STICKY;
    }
    

    Think yourself before you copy-paste anything ...

    0 讨论(0)
  • 2020-12-03 02:20

    For background operations, you can use WorkManager.

    0 讨论(0)
提交回复
热议问题