Update UI while working on background

android, multithreading

Solution

public class MyServce extends Service{
public static final String BROADCAST_ACTION = "com.myapp";
Intent intent;
private final Handler handler = new Handler();

@Override
public void onCreate()
{
    super.onCreate();
    intent = new Intent(BROADCAST_ACTION);
}

 @Override
    public void onStart(Intent intent, int startId) {
        handler.removeCallbacks(sendUpdatesToUI);
        handler.postDelayed(sendUpdatesToUI, 1000); // 1 second

    }
   private Runnable sendUpdatesToUI = new Runnable() {
        public void run() {
            DoYourWorking();        
            handler.postDelayed(this, 1000); // 1 seconds
        }

        private void DoYourWorking() {
        ........
                    ........
                     intent.putExtra("key", progress);
             sendBroadcast(intent);

        }
    };   

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}
@Override
public void onDestroy() {   
    super.onDestroy();
    handler.removeCallbacks(sendUpdatesToUI);       

}

Now in your Activity register broadcast to service

private BroadcastReceiver brodcast = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
                 //intent.getWhatever
        // update your progress
        //progressbar.setProgress 
    }

register broadcast

 registerReceiver(brodcast, new IntentFilter(MyService.BROADCAST_ACTION));

Problem

I have an update database operation, that has an activity, which keeps updating the percentage and it runs inside an AsyncTask. Inside doInBackground() I call the controller that updates the database and keep updating the percentage on the activity, however, if I press home button or back button, the operation is cancelled. What u suggest me to do? I was trying to start a Service inside doInBackground() so it would run in background, but it looks like its not working. My code looks like this: ``` public class UpdateDatabaseAsyncTask extends AsyncTask<Void, Integer, Integer> { @Override public void onPreExecute() { mCustomProgressBar.startAnimation(); } @Override public Integer doInBackground(Void... params) { return mController.updateDatabase(); } @Override public void onPostExecute(Integer result) { mCustomProgressBar.stopAnimation(); // finish the activity } @Override public void onProgressUpdate(Integer... value) { updatePercentageValue(value[0]); } public void callPublishProgress(Integer value) { publishProgress(value); } } ``` And inside the controller I call the method `callPublishProgress(value)` passing the current percentage value, so it will `publishProgress(value)` in the UI. I was debugging, and I pressed the home/back button, and it just stopped running the worker thread. Another solution I tried, was starting a Service to run in background no matter the user press home/back button or not, so I thought, and the Service would make a call to the controller method that does the work, and it would call the `callPublishProgress(value)` to update the percentage value on the UI anyways. However, what was happening is, the code reach `doInBackground()` and start the service, but it goes to `onPostExecute()` immediately, it just didn't wait the service to finish(of course!). So it gives a `NullPointerException`. I thought of making a loop inside `doInBackground()` with a flag set in the Service, so it would leave this loop while the service hasn't been finished (I was using an IntentService), but it didn't work anyways. I thought of using a Timer too. But I don't know. I was reading the articles in documentation about Threads, etc. And it suggests using `AsyncTask`, just as I was trying to do. It also talks about `runOnUiThread(Runnable)`. Anyways what I need is to make an operation in background(probably using an IntentService), so no matter if the user press the home button, it will keep running, but it must update the percentage on the UI, and when the user leave the screen and back to it, it shows the current percentage value updated in the screen. What is the best solution for my case? Thanks.

Original source