I am developing an app where in a number of the activities I need to retrieve data via Http. Once I have the data I process it in the onPostExecute() callback method.
This works fine if I define the async task as an inline class, but as I want to do the same processing in a number of activities I have defined it as an external class.
So the question is, using an external class how do I signal an "event" back to the calling class as a means of passing the data back. I know how to do this in C# but I am new to Java and can not see how to achieve this.
While it is true that a Listener technically correct, I would claim that it is either too complicated or not complicated enough.
Here's an easier solution:
class Foo {
class Bar extends AsyncTask<Void, Void, Result> {
public void onPostExecute(Result res) {
doSomething(res);
}
}
public void doSomething(Result res) {
/// process result
}
public void startTask() {
new Bar().execute();
}
}
Is equivalent to:
class Bar extends AsyncTask<Void, Void, Result> {
private final Foo foo;
public Bar(Foo foo) { this.foo = foo; }
public void onPostExecute(Result res) {
foo.doSomething(res);
}
}
class Foo {
public void doSomething(Result res) {
/// process result
}
public void startTask() {
new Bar(this).execute();
}
}
... which is what you asked: when you pull the inner class out, you lose the implicit pointer. Just make it explicit and pass it in.
The bad news is that there are all sorts of memory leak and lifecycle issues that arise from this solution. I would very much recommend that, before your program gets even bigger, you looking into using an IntentService instead of an AsyncTask and use a Handler, or Activity.runOnUiThread to get the results back onto the UI thread.
One approach:
Define a parent abstract class called ParentActivity
(extend Activity of course). Have that contain an abstract method called onAsyncCallback();
Have each class that uses the task to extend that class and implement the method.
In your AsyncTask constructor, have it accept in a ParentActivity
.
Eg
ParentActivity activity;
public MyTask (ParentActivity myActivity)
{
this.activity = myActivity;
}
When done in onPostExecute()
, simply do
activity.onAsyncCallback(data);
This would also work with an interface, it does the same thing, except intead you have the Constructor accept in the Listener instance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With