title: Does the presenter having knowledge of the Activity / Context a bad idea in the MVP pattern?
body: <p>I've been playing around with the MVP pattern for a few weeks now and I've come to the point where I need context to start a <code>service</code> and access <code>Shared Preferences</code>.</p>
  
  <p>I've read that the purpose of MVP is to decouple the view from the logic and having <code>context</code> within a <code>Presenter</code> may defeat that purpose (correct me if I'm wrong on this).</p>
  
  <p>Currently, I have a LoginActivity that looks something like this:</p>
  
  <p><strong>LoginActivity.java</strong></p>
  
  <pre><code>public class LoginActivity extends Activity implements ILoginView {
  
      private final String LOG_TAG = "LOGIN_ACTIVITY";
  
      @Inject
      ILoginPresenter mPresenter;
      @Bind(R.id.edit_login_password)
      EditText editLoginPassword;
      @Bind(R.id.edit_login_username)
      EditText editLoginUsername;
      @Bind(R.id.progress)
      ProgressBar mProgressBar;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_login);
          MyApplication.getObjectGraphPresenters().inject(this);
          mPresenter.setLoginView(this, getApplicationContext());
      }
  
      @Override
      public void onStart() {
          mPresenter.onStart();
          ButterKnife.bind(this);
          super.onStart();
      }
  
      @Override
      public void onResume() {
          mPresenter.onResume();
          super.onResume();
      }
  
      @Override
      public void onPause() {
          mPresenter.onPause();
          super.onPause();
      }
  
      @Override
      public void onStop() {
          mPresenter.onStop();
          super.onStop();
      }
  
      @Override
      public void onDestroy() {
          ButterKnife.unbind(this);
          super.onDestroy();
      }
  
      @OnClick(R.id.button_login)
      public void onClickLogin(View view) {
          mPresenter.validateCredentials(editLoginUsername.getText().toString(),
                  editLoginPassword.getText().toString());
      }
  
      @Override public void showProgress() { mProgressBar.setVisibility(View.VISIBLE); }
  
      @Override public void hideProgress() {
          mProgressBar.setVisibility(View.GONE);
      }
  
      @Override public void setUsernameError() { editLoginUsername.setError("Username Error"); }
  
      @Override public void setPasswordError() { editLoginPassword.setError("Password Error"); }
  
      @Override public void navigateToHome() {
          startActivity(new Intent(this, HomeActivity.class));
          finish();
      }
  }
  </code></pre>
  
  <p><strong>Presenter Interface   ILoginPresenter.java</strong></p>
  
  <pre><code>public interface ILoginPresenter {
      public void validateCredentials(String username, String password);
  
  
      public void onUsernameError();
  
      public void onPasswordError();
  
      public void onSuccess(LoginEvent event);
  
      public void setLoginView(ILoginView loginView, Context context);
  
      public void onResume();
  
      public void onPause();
  
      public void onStart();
  
      public void onStop();
  }
  </code></pre>
  
  <p>Lastly, my Presenter:</p>
  
  <p><strong>LoginPresenterImpl.java</strong></p>
  
  <pre><code>public class LoginPresenterImpl implements ILoginPresenter {
  
      @Inject
      Bus bus;
  
      private final String LOG_TAG = "LOGIN_PRESENTER";
      private ILoginView loginView;
      private Context context;
      private LoginInteractorImpl loginInteractor;
  
      public LoginPresenterImpl() {
          MyApplication.getObjectGraph().inject(this);
          this.loginInteractor = new LoginInteractorImpl();
      }
  
      /**
       * This method is set by the activity so that way we have context of the interface
       * for the activity while being able to inject this presenter into the activity.
       *
       * @param loginView
       */
      @Override
      public void setLoginView(ILoginView loginView, Context context) {
          this.loginView = loginView;
          this.context = context;
  
          if(SessionUtil.isLoggedIn(this.context)) {
              Log.i(LOG_TAG, "User logged in already");
              this.loginView.navigateToHome();
          }
      }
  
      @Override
      public void validateCredentials(String username, String password) {
          loginView.showProgress();
          loginInteractor.login(username, password, this);
      }
  
      @Override
      public void onUsernameError() {
          loginView.setUsernameError();
          loginView.hideProgress();
      }
  
      @Override
      public void onPasswordError() {
          loginView.setPasswordError();
          loginView.hideProgress();
      }
  
      @Subscribe
      @Override
      public void onSuccess(LoginEvent event) {
          if (event.getIsSuccess()) {
              SharedPreferences.Editor editor =
                      context.getSharedPreferences(SharedPrefs.LOGIN_PREFERENCES
                              .isLoggedIn, 0).edit();
              editor.putString("logged_in", "true");
              editor.commit();
  
              loginView.navigateToHome();
              loginView.hideProgress();
          }
      }
  
      @Override
      public void onStart() {
          bus.register(this);
      }
  
      @Override
      public void onStop() {
          bus.unregister(this);
  
      }
  
      @Override
      public void onPause() {
  
      }
  
      @Override
      public void onResume() {
      }
  }
  </code></pre>
  
  <p>As you can see, I passed the context from the <code>Activity</code> into my <code>Presenter</code> just so I can access the <code>Shared Preferences</code>. I'm quite worried about passing the context into my presenter. Is this an okay thing to do? Or should I be doing it some other way?</p>
  
  <p><strong>EDIT Implemented Jahnold's 3rd preference</strong></p>
  
  <p>So let's ignore the interface and implementation because it's pretty much the entire thing. So now I'm <code>injecting</code> the interface for the Sharedpreference into my presenter. Here's my code for the <code>AppModule</code></p>
  
  <p><code>AppModule.java</code> </p>
  
  <pre><code>@Module(library = true,
      injects = {
              LoginInteractorImpl.class,
              LoginPresenterImpl.class,
              HomeInteractorImpl.class,
              HomePresenterImpl.class,
  
      }
  )
  public class AppModule {
  
      private MyApplication application;
  
      public AppModule(MyApplication application) {
          this.application = application;
      }
  
      @Provides
      @Singleton
      public RestClient getRestClient() {
          return new RestClient();
      }
  
      @Provides
      @Singleton
      public Bus getBus() {
          return new Bus(ThreadEnforcer.ANY);
      }
  
      @Provides
      @Singleton
      public ISharedPreferencesRepository getSharedPreferenceRepository() { return new SharedPreferencesRepositoryImpl(application.getBaseContext()); }
  
      }
  }
  </code></pre>
  
  <p>The way I get the context is from <code>MyApplication.java</code></p>
  
  <p>When the application begins, I make sure to create this Object graph with this line of code:</p>
  
  <pre><code>objectGraph = ObjectGraph.create(new AppModule(this));
  </code></pre>
  
  <p>Is this okay? I mean I now don't have to pass the context from the activity into my presenter, but I still have context of the application.</p>