Search code examples
javaandroiddependency-injectioncircular-dependency

How to avoid circular dependency between two classes?


I have two classes - one defines BaseActivity (a global parent for all my activities in the app) and other is an AsyncTask class in which I defined common networking operation. But I have next problem. AsyncTask class named RestfulNetworkTasks in his onPostExecute() method must call UpdateCurrentActivityAfterNetworkOperation() which is defined in BaseActivity class but BaseActivity class also have to create an instance of RestfulNetworkTasks. Here is code which illustrates this problem clearly.

class RestfulNetworkTasks extends AsyncTask<Pair<String, LinkedHashMap<String, Object>>, Void, LinkedHashMap<String, Object>> {
    private ImmutableMap<String, Object> serverData_;
    NetworkOperation LowLevelRestOperations_ = new NetworkOperation();

    @Override
    protected LinkedHashMap<String, Object> doInBackground(Pair<String, LinkedHashMap<String, Object>>... params) {
        return LowLevelRestOperations_.executeServerCommand(params[0].getValue0(), params[0].getValue1());
    }

    protected void onPostExecute(LinkedHashMap<String, Object> result) {
        serverData_ = copyOf(result);
        BaseActivity instance_Activity = new BaseActivity(); 
        //BaseActivity injection (It is too bad to create Activity in such a way - I know!) So I need some piece of advice
        instance_Activity.UpdateCurrentActivityAfterNetworkOperation(serverData_);
        //Here I must call method for updating GUI after operation
    }

    public ImmutableMap<String, Object> GetDataFromServer() {
        return serverData_;
    }
}

public class BaseActivity extends Activity {

    RestfulNetworkTasks serverOperation_ = new RestfulNetworkTasks(); //RestfulNetworkTasks injection

    public void UpdateCurrentActivityAfterNetworkOperation(
        ImmutableMap<String, Object> server_data) {
    }// Here is this method which I will override in my child activities

    @SuppressWarnings("unchecked")
    public ImmutableMap<String, Object> Login(LinkedHashMap<String, Object> parameters) {
        Pair<String, LinkedHashMap<String, Object>> params_ = new Pair<String, LinkedHashMap<String, Object>>(LOGIN_COMMAND, parameters);
        serverOperation_.execute(params_);
        return serverOperation_.GetDataFromServer();
    }
}

As you see i have a circular dependency here between RestfulNetworkTasks and BaseActivity classes which may cause infinite chain calls of constructors.

The question how can I refactor this design to avoid this?


Solution

  • The AsyncTask will amost always be called from an Activity, so why not just pass it in as a Constructor argument?

    RestfulNetworkTasks.java:

    private BaseActivity activity;
    
    public RestfulNetworkTasks(BaseActivity activity){
        this.activity = activity;
    }
    

    BaseActivity.java:

    new RestfulNetworkTasks(this).execute();