Q:

Safely refresh activity details from AsyncTask

I have an Android app with an associated website. 
I've a LoginActivity which accepts user credentials, uses an AsyncTask subclass to verify them with the website, and if correct stores them in SharedPreferences for future use.
I've a MainActivity which displays user details, based on those SharedPreferences values.
So when the AsyncTask completes, I need to refresh the user details displayed in the Main activity.

I could do this by passing a reference to the MainActivity to the LoginActivity when calling it, and then in the AsyncTask onPostExecute, call a function in that MainActivity instance to refresh the displayed data.
This seems to be a common way of doing it, but I'm not sure if it's completely safe. It's unlikely, but what happens if the MainActivity is terminated by the OS while the AsyncTask is still processing? 
Alternatively, in this instance I could just finish() the MainActivity when I start the LoginActivity, and launch a new MainActivity from the onPostExecute which would display the refreshed data.
But I may have other activities where user interaction is proceeding while a background AsyncTask is refreshing data - in those cases the second method won't work.

Just wondering if there's a better way of doing it, or is the first way safe enough?

A:

I could do this by passing a reference to the MainActivity to the LoginActivity when calling it, and then in the AsyncTask onPostExecute, call a function in that MainActivity instance to refresh the displayed data.

The out-of-the-box way of dealing with activities coming and going is to use AsyncTaskLoader. This approach implements @ByteMe's suggestion to unregister/register activity instances. Unfortunately, its programmer API is... less than painless. In particular, the API is written for a screen that begins loading immediately when it's opened. Using the Loaders API in a screen that begins loading upon user interaction is perfectly possible, but the implementation is a bit awkward.
A common alternate approach –still using only core- and support-v4 library classes– is to use an IntentService to do the background work and the LocalBroadcastManager to deliver the result.
If using Open Source libraries is an option, you might want to look at Otto Bus or RxJava to deliver the "load finished" event.

Alternatively, in this instance I could just finish() the MainActivity when I start the LoginActivity, and launch a new MainActivity from the onPostExecute which would display the refreshed data.

If I understand correctly, the MainActivity is your launch activity. The first thing it does is check if login is necessary and, if it is, it directs to LoginActivity. If login isn't necessary, it shows the account data and if it is, it waits for LoginActivity to return.
This sounds to me like a perfect fit for startActivityForResult(Intent, int). Just have the main activity launch the login activity with a request code. The login activity can call setResult(int, Intent) with a return code and the authentication data. The main activity can then implement onActivityResult() to get the return value from the login activity and do all that needs to be done. 
As an added benefit, you can centralise all SharedPreferences interaction in the main activity and keep it entirely outside login activity. This makes for lower coupling between the two.
An entirely different approach that you could consider is to ditch user authentication entirely and rely on Google+ Sign-in to identify users by their Google+ account. You can do the same through Facebook. On the upside, using either of these (or both) will completely free you from the responsibility of managing authentication and credentials in a secure way. On the downside, there's vendor lock-in and it may scare off some users.

