¿Cómo usar las Preferencias Compartidas en MVP sin Dagger y no hacer que Presenter dependa del contexto?

Estoy tratando de implementar MVP sin Dagger (para fines de aprendizaje). Pero llegué al problema – Yo uso Repository patter para obtener datos en bruto ya sea de caché (Preferencias compartidas) o de la red:

Shared Prefs| |<->Repository<->Model<->Presenter<->View Network| 

Pero para poner mis manos en las preferencias compartidas tengo que poner en algún lugar como línea

 presenter = new Presenter(getApplicationContext()); 

getLastCustomNonConfigurationInstance par onRetainCustomNonConfigurationInstance / getLastCustomNonConfigurationInstance para mantener el presentador "retenido".

 public class MyActivity extends AppCompatActivity implements MvpView { @Override protected void onCreate(Bundle savedInstanceState) { //... presenter = (MvpPresenter) getLastCustomNonConfigurationInstance(); if(null == presenter){ presenter = new Presenter(getApplicationContext()); } presenter.attachView(this); } @Override public Object onRetainCustomNonConfigurationInstance() { return presenter; } //... } 

Entonces, ¿cómo usar las Preferencias Compartidas en MVP sin Dagger y no hacer que Presenter dependa del Contexto?

4 Solutions collect form web for “¿Cómo usar las Preferencias Compartidas en MVP sin Dagger y no hacer que Presenter dependa del contexto?”

Su presentador no debe depender del Context en primer lugar. Si su presentador necesita SharedPreferences debe pasarlos en el constructor .
Si su presentador necesita un Repository , de nuevo, ponga eso en el constructor . Le recomiendo que vea las conversaciones de código limpio de Google ya que hacen un trabajo realmente bueno al explicar por qué debe usar una API adecuada.

Esta es la gestión de dependencias adecuada, que le ayudará a escribir código limpio, mantenible y comprobable. Y si usas dagas, alguna otra herramienta DI, o suministras los objetos tú mismo es irrelevante.

 public class MyActivity extends AppCompatActivity implements MvpView { @Override protected void onCreate(Bundle savedInstanceState) { SharedPreferences preferences = // get your preferences ApiClient apiClient = // get your network handling object Repository repository = new Repository(apiClient, preferences); presenter = new Presenter(repository); } } 

Esta creación de objetos se puede simplificar usando un patrón de fábrica, o algún marco DI como daga, pero como se puede ver arriba, ni el Repository ni su presentador dependen de un Context . Si desea proporcionar sus SharedPreferences reales, sólo su creación dependerá del contexto.

Su repositorio depende de algún cliente api y SharedPreferences , su presentador depende del Repository . Ambas clases se pueden probar fácilmente suministrándoles objetos burlones.

Sin código estático. Sin efectos secundarios.

Puede utilizar el contexto de la Application en la capa del Repository sin pasar por Presenter como se explica aquí . Primero subclase su clase Application y guarde su instancia en una variable estática.

 public class MyApplication extends Application { private static context = null; public void onCreate(...) { context = this; ... } public static Context getContext() { return context; } } 

A continuación, mencione su nombre de clase de aplicación en el AndroidManifest ,

 <application android:name=".MyApplication" ... > </application> 

Ahora puede utilizar el contexto de la aplicación dentro del repositorio (ya sea a SharedPreferences, base de datos SQLite, acceso a la red), utilizando MyApplication.context .

Así es como lo hago. Tengo una clase singleton "SharedPreferencesManager" que manejará todas las operaciones de lectura de escritura a los prefios compartidos como a continuación

 public final class SharedPreferencesManager { private static final String MY_APP_PREFERENCES = "ca7eed88-2409-4de7-b529-52598af76734"; private static final String PREF_USER_LEARNED_DRAWER = "963dfbb5-5f25-4fa9-9a9e-6766bfebfda8"; ... // other shared preference keys private SharedPreferences sharedPrefs; private static SharedPreferencesManager instance; private SharedPreferencesManager(Context context){ //using application context just to make sure we don't leak any activities sharedPrefs = context.getApplicationContext().getSharedPreferences(MY_APP_PREFERENCES, Context.MODE_PRIVATE); } public static synchronized SharedPreferencesManager getInstance(Context context){ if(instance == null) instance = new SharedPreferencesManager(context); return instance; } public boolean isNavigationDrawerLearned(){ return sharedPrefs.getBoolean(PREF_USER_LEARNED_DRAWER, false); } public void setNavigationDrawerLearned(boolean value){ SharedPreferences.Editor editor = sharedPrefs.edit(); editor.putBoolean(PREF_USER_LEARNED_DRAWER, value); editor.apply(); } ... // other shared preference accessors } 

Entonces, siempre que se necesite acceso a la preferencia compartida, paso el objeto SharedPreferencesManager en el constructor de Presenter relevante. Por ejemplo :

 if(null == presenter){ presenter = new Presenter(SharedPreferencesManager.getInstance(getApplicationContext())); } 

¡Espero que esto ayude!

La respuesta de Many Overflow el 10 de mayo '16 a las 12:29 funcionó para mí. Sin embargo, la inicialización del presentador con getApplicationContext () guardó los datos en SharedPreferences siempre y cuando la Actividad estuviera viva. No se encontraron datos guardados cada vez que se recreaba la actividad. Inicializar el presentador de un fragmento utilizando getActivity () resolvió el problema.

 if(null == presenter){ presenter = new Presenter(SharedPreferencesManager.getInstance(getActivity())); } 
  • Cómo tratar las preferencias compartidas almacenadas en una biblioteca
  • Acceder a las preferencias compartidas a través de las actividades
  • Lectura de datos SharedPreferences en Fragment, dentro de FragmentActivity
  • SharedPreferences strage. getSharedPreferences no funciona
  • Android: obtiene los elementos de la matriz de cadenas y muestra uno por uno en la vista de texto
  • SharedPreference cometido en SyncAdapter no actualizado en Activity?
  • Copia de seguridad / restauración de preferencias compartidas android
  • ¿Cómo actualizar SharedPreferences en android cuando restaura desde un archivo?
  • Manejo de varias instancias de appwidget
  • ¿Restablecer SharedPreferences?
  • Almacenar objeto de lista de matrices en SharedPreferences
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.