Getting Reference to Calling Activity from AsyncTask (NOT as an inner class)

时光毁灭记忆、已成空白 提交于 2019-12-06 01:01:14

问题


Is it at all possible, from within an AsyncTask that is NOT an inner class of the calling Activity class, to get a reference to the instance of Activity that initiated execution of the AsyncTask?

I am aware of this thread, however it doesn't exactly address how to reference the calling Activity. Some suggest passing a reference to the Activity as a parameter to the AsyncTask constructor, however, it's reported that doing so will always result in a NullPointerException.

So, I'm at a loss. My AsyncTask provides robust functionality, and I don't want to have to duplicate it as an inner class in every Activity that wants to use it. There must be an elegant solution.


回答1:


The "elegant solution" is to actually try passing it as a parameter (to the constructor or execute()) and see if it works, rather than assuming the person who asked that previous question (then answered his own question twice) knows what he is doing. I can think of nothing intrinsic to AsyncTask that would cause Activity to be a bad constructor parameter and every other object be just fine.

Now, I haven't passed an Activity (or other Context) as a parameter to an AsyncTask, because my AsyncTasks are always private inner classes. In fact, the fact that you want a public AsyncTask to me is a code smell, suggesting these tasks should be mediated by a Service or some other control point. But, that's just me.

UPDATE

A better answer for handling this pattern can be found here: Background task, progress dialog, orientation change - is there any 100% working solution?




回答2:


My AsyncTasks always live in a separate package while still bound to a particular type of Activity. They accept it's instance in constructor and store in a local variable.
Try thinking in terms of creating an abstract Activity class that encapsulates AsyncTask-related stuff and is extended by other activities.
Like so:

public abstract RemoteListActivity<T> extends ListActivity{

// calls AsyncTask, shows spinning progress dialog, etc

protected abstract T someConcreteMethod();

}

public final class CustomerListActivity extends RemoteListActivity<Customer>{

protected final Customer someConcreteMethod();

}

Alternatively, if things don't fit in a single hierarchy, have an interface:

interface LazyLoadable {
    void setLoadingState();
    void setDefaultState();
}

public class MyActivity extends Activity implements LazyLoadable{
}

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

    private final LazyLoadable lazyLoadable;

    public MyAsyncTask(Context ctx, LazyLoadable lazyLoadable){
        super(ctx);
        this.lazyLoadable = lazyLoadable;
    }

}


来源:https://stackoverflow.com/questions/2719433/getting-reference-to-calling-activity-from-asynctask-not-as-an-inner-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!