How to use Shared Preferences in MVP without Dagger and not causing Presenter to be Context dependent?

前端 未结 4 1768
北恋
北恋 2020-12-23 11:51

I\'m trying to implement MVP without Dagger (for learning purposes). But I got to the problem - I use Repository patter to get raw data either from cache (Shared Preferences

4条回答
  •  萌比男神i
    2020-12-23 12:17

    Another approach can also be found in the Android Architecture libraries:

    As the Shared Preferences depends on a context, it solely should know about it. To have things in one place, I choose a Singleton to manage this. It consists of two classes: the Manager (i.e. the SharePreferenceManager or ServiceManager or whatever), and an initializer which injects the Context.

    class ServiceManager {
    
      private static final ServiceManager instance = new ServiceManager();
    
      // Avoid mem leak when referencing context within singletons
      private WeakReference context
    
      private ServiceManager() {}
    
      public static ServiceManager getInstance() { return instance; }
    
      static void attach(Context context) { instance.context = new WeakReference(context); }
    
      ... your code...
    
    }
    

    The initializer is basically an empty Provider (https://developer.android.com/guide/topics/providers/content-providers.html), which is registered in the AndroidManifest.xml and loaded when the app starts:

    public class ServiceManagerInitializer extends ContentProvider {
    
        @Override
        public boolean onCreate() {
            ServiceManager.init(getContext());
    
            return false;
        }
    
        @Nullable
        @Override
        public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
            return null;
        }
    
        @Nullable
        @Override
        public String getType(@NonNull Uri uri) {
            return null;
        }
    
        @Nullable
        @Override
        public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
            return null;
        }
    
        @Override
        public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
            return 0;
        }
    
        @Override
        public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
            return 0;
        }
    }
    

    All function are default implementations except the onCreate, which injects the required context into our manager.

    Last step to get this working is to register the provider in the manifest:

    
    

    This way, your service manager is decoupled from any external context initialization. It now can be completely replaced with another implementation which is context-independent.

提交回复
热议问题