Reputation: 1461
I would like to achieve the following behaviour, but I'm not sure how:
Is there a way of achieving this behaviour?
Thank you
Upvotes: 1
Views: 2070
Reputation: 36302
A Service is a component that allows some code to have a separate lifetime outside of activities without interacting with the user. As others have mentioned, that's certainly one option to consider. If you go with that, IntentService is the easiest way to make the work asynchronous.
However, you could continue to use AsyncTask and just add some code to signal that it's "complete". This is the case when the background work no longer matters if your application is killed, and you're OK with your app being killed before this work completes if the user leaves the application. Another way to see this is if the result of the AsyncTask only matters to either/both of these two activities and not outside. This is an important difference in requirements from needing a Service which again, provides a lifetime outside of activities.
To pass the data, take a look at this doc. There are a lot of ways you could tackle this, but for this kind of thing I prefer a pseudo-singleton approach. (I don't like to use SharedPreferences to pass data, because frankly I don't think that's what the class is for. I prefer this pseudo-singleton approach over a pure singleton because it's more testable. Android uses the singleton approach all over the place though.) I'd create a reference to some sort of AsyncTask registrar class in the Application object. As the Application object is accessible from both activities, the first one can register your AsyncTask with the registrar and the second one can get that AsyncTask and register to listen for completion if it hasn't already finished.
Upvotes: 0
Reputation: 14386
This is a way to do exactly what you want, assuming that the result is an int. You can extend this property, using a parcelable object. Probably, using a Service is still the best choice.
1) Create a class, called Result, that is a wrapper for your result. It must implement the Parcelable interface:
public class Result implements Parcelable {
private int result;
public Result(int i) {
super();
result = i;
}
public void setResult(int result) {
this.result = result;
}
public int getResult() {
return result;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(result);
}
public static final Parcelable.Creator<Result> CREATOR = new Parcelable.Creator<Result>() {
public Result createFromParcel(Parcel in) {
return new Result(in);
}
public Result[] newArray(int size) {
return new Result[size];
}
};
public Result(Parcel in) {
result = in.readInt();
}
}
2) Now, you can use a Result object as a private variable of the first activity:
public class FirstActivity extends Activity {
private Result result;
....
}
3) In your firstActivity, you can start an AsyncTask with a line like this:
new MyAsyncTask(result).execute();
4) Your AsyncTask can be made in this way:
class MyAsyncTask extends AsyncTask<Void, Void, Void> { // you can modify types as you want
Result result;
public MyAsyncTask(Result result) {
this.result = result;
}
....
public mySetResult() {
result.setResult(...); //set your value
}
....
}
5) When you start the second Activity, you can pass your result object to the second activity:
Intent i = new Intent(getApplicationContext(), SecondActivity.class);
i.putExtra("parc", result);
startActivity(i);
6) Finally, from the second activity, you can obtain the result using this code:
Result res = (Result) getIntent().getParcelableExtra("parc");
For more details about parcelable object, can see Android Developer
Upvotes: 0
Reputation: 13564
I've been using a variation of what was suggested by Chris:
Start by creating an IntentService, which is the easiest kind of Service
to create. Then use SharedPreferences to indicate the state of your IntentService
and share values between your Service
and Activities
. Your Activity
can register itself as an OnSharedPreferenceChangeListener in order to know when your Service is done doing work and/or another SharedPreference it cares about has changed.
With IntentService
, all you need to do is override the onHandleIntent
method. Everything inside onHandleIntent will run on a background thread.
Upvotes: 0