yslr
yslr

Reputation: 107

Android Update Current Activity From Background Thread

My application has a refresh button on the main activity. When the user presses that button, a new thread is created which starts updating the SQLite database. When this thread started, user could possibly get into another activies of the application.

The problem is these other activities(ListActivity) should be updated according to the DB when that background thread is completed. How could I provide that. I tried getting current task with ActivityManager but It requires extra permission which I dont want.

Upvotes: 1

Views: 2638

Answers (2)

Joseph Earl
Joseph Earl

Reputation: 23432

Edit:

Sorry seems I misunderstood you. Please take a look at the following code, it is similar to Chinaski's (you just use an interface for the callback methods) but I added a bit more to ensure you know how to use it in a way that will avoid memory leaks.

Note how the activity detaches during onDestroy -- alternatively you could use a WeakReference, however these days you'd use a Fragment with setRetainInstance(true) and completely avoid the detaching/attaching as the fragment would be retained.

MyAsyncTask

public class MyAsyncTask extends AsyncTask<Void, Void, Void> {

    private Callback mCallback;

    private boolean mIsComplete = false;

    private boolean mHasCallbackBeenCalled = false;

    public MyBackgroundTask(Callback callback) {
        mCallback = callback;
    }

    /** Only safe to call this from the UI thread */
    public void attach(Callback callback) {
        mCallback = callback;

        if (mIsComplete && !mHasCallbackBeenCalled) {
            fireCallback();
        }
    }

    /** Only safe to call this from the UI thread */
    public void detach() {
        mCallback = callback;
    }

    @Override
    public void doInBackground() {
        // do the heavy stuff here
        return null;
    }

    @Override
    public void onPostExecute(Void result) {
        mIsComplete = true;
        fireCallback();
    }

    private void fireCallback() {
        if (mCallback != null) {
            mCallback.callbackMethod();
            mHasCallbackBeenCalled = true;
        }
    }

    public static interface Callback {

        public void callbackMethod();

    }
}

MyActivity

public class MyActivity extends Activity implements MyAsyncTask.Callback {

    private MyAsyncTask mTask;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Check for a retained task after a configuration change
        // e.g. a rotation
        if (getLastNonConfigurationInstance() != null) {
            mTask = (MyAsyncTask) getLastNonConfigurationInstance();
            // Re-attach the task
            mTask.attach(this);
        }
    }

    @Override
    public void onDestroy() {
        // Detach from task to avoid memory leak
        if (mTask != null) {
            mTask.detach();
        }

        super.onDestroy();
    }

    @Override
    public Object onRetainNonConfigurationInstance() {
        // Retain the async task duration a rotation
        return mTask;
    }

    /** Callback method */
    @Override
    public void callbackMethod() {
        // Do something here
    }

}

Upvotes: 1

AMerle
AMerle

Reputation: 4354

You could make a singleton in which you will have your thread and a queue of "tasks". When a task is finished, you check / launch the next task, and when you add a task, you launch it, or add it in the queue if a task is already running.

I don't say this is the best solution, but it's one.

Upvotes: 0

Related Questions