2016-11-21 4 views
0

Ich arbeite mit MVP-Struktur mit Dolch 2Inject bestehende MVP Moderator von Aktivität in dem Service über Dagger2

Ich kann mit Activity & Fragment über Eigentum Injektion wirklich gut funktionieren, eine Instanz eines Vortragende zu erhalten, BaseTopPresenter.

Mein Problem ist, ich brauche meinen Moderator BaseTopPresenter presenter; in einen Dienst FirebaseMsgService, ohne ich die statische Methode getComponent() in der Aktivität zu injizieren, um die Komponente zu erhalten und inject() rufen Sie den Moderator BaseTopPresenter zu bekommen.

p/s: Ich dachte über LocalBroadcastReceiver UI-Updates von der Service zu tun, aber ich versuche, MVP zu tun. Bitte helfen Sie mir, indem Sie eine elegante Möglichkeit bereitstellen, eine Instanz des Präsentators in meinem Service zu erhalten, da ich viele Anwendungsfälle dafür habe.

innen MainApplication.java:

public class MainApplication extends Application { 

    /** 
    * Dagger 2 
    */ 
    private AppComponent appComponent; 

    public static AppComponent getAppComponent(Context context) { 
     return ((MainApplication) context.getApplicationContext()).appComponent; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     // Dagger 2 
     appComponent = DaggerAppComponent.builder() 
       .appModule(new AppModule(this)) 
       .networkModule(new NetworkModule(getString(R.string.base_url))) 
       .build(); 
    } 
    } 

innen FirebaseMsgService.java:

@ActivityScope 
public class FirebaseMsgService extends FirebaseMessagingService { 

    @Inject 
    BaseTopPresenter presenter; 
    @Inject 
    PreferenceStore preferences; 

    @Override 
    public void onMessageReceived(RemoteMessage remoteMessage) { 
     super.onMessageReceived(remoteMessage); 

     // Dagger 2 : ACTUALLY I DON'T WANT USE THIS STATIC METHOD ANYMORE 
     // I'M TRYING TO FIND THE OTHER WAY TO GET EXISTED PRESENTER VIA @INJECT HERE 
     BaseActivity.getAsukabuComponent().inject(this); 

     if (remoteMessage != null) sendNotification(remoteMessage); 
    } 

    private void sendNotification(RemoteMessage remoteMessage) { 
     NotificationManager notificationManager = (NotificationManager) 
       getSystemService(Context.NOTIFICATION_SERVICE); 
     // PRESENTER AS PARAMETER 
     CustomizeNotification customizeNotification = 
       new CustomizeNotification(this, presenter, remoteMessage); 

     notificationManager.notify(customizeNotification.getNotifyType(), customizeNotification.build()); 
    } 

} 

innen CustomizeNotifications.java:

public class CustomizeNotification extends NotificationCompat.Builder { 

private BaseTopPresenter presenter; 

// Data 
private static final int NEW_FOLLOWER = 1; 

private static final String KEY_IS_FOLLOWER = "is_follower"; 
private static final String KEY_NOTIFICATION_MESSAGE = "notification_message"; 
private static final String KEY_EXTRA_NOTIFICATION_DATA = "KEY_EXTRA_NOTIFICATION_DATA"; 

private int notifyType = 0; 
private RemoteMessage remoteMessage; 

// The others 
private Context context; 

public CustomizeNotification(Context context, BaseTopPresenter presenter, RemoteMessage remoteMessage) { 
    super(context); 

    this.presenter = presenter; 
    this.context = context; 
    this.remoteMessage = remoteMessage; 

    // Inject dagger 2 
    Map<String, String> map = remoteMessage.getData(); 

    Bundle mBundle = new Bundle(); 
    for (Map.Entry<String, String> entry : map.entrySet()) 
     mBundle.putString(entry.getKey(), entry.getValue()); 

    Intent intent = new Intent(context, StockActivity.class); 
    intent.putExtra(KEY_EXTRA_NOTIFICATION_DATA, mBundle); 

     notifyType = Integer.valueOf(mBundle.getString(KEY_NOTIFY_TYPE)); 

     switch (notifyType) { 
      case NEW_FOLLOWER: 
       if (remoteMessage.getNotification().getBody() != null) 
        implementFollower(intent, mBundle, remoteMessage.getNotification().getBody()); 
       break; 
     } 
} 

private void implementFollower(Intent intent, Bundle mBundle, String body) { 
     // Show dialog only 
     runInForeground(mBundle); 
} 

private void runInForeground(Bundle mBundle) { 
    // Handler 
    Handler handler = new Handler(Looper.getMainLooper()); 

    // Foreground : I NEED UPDATE EXISTED DATA ON UI IN HERE 
    handler.post(() -> { 
     presenter.updateNotification(mBundle); 
    }); 
} 
} 

innen BaseTopPresenter.java:

0.123.
@ActivityScope 
public class BaseTopPresenter extends BasePresenter { 
@Inject 
    public BaseTopPresenter(AsukabuApi asukabuApi, PreferenceStore preferenceStore) { 
     super(asukabuApi, preferenceStore); 
    } 

public void updateNotification(Bundle mBundle) { 
     if (notificationView != null) notificationView.onUpdateNotifications(mBundle); 
    } 
} 

innen BaseTopActivity.java:

@ActivityScope 
    public abstract class BaseTopActivity extends BaseActivity implements  BaseTopView, BaseTopView.NotificationView { 
    @Inject 
    BaseTopPresenter baseTopPresenter; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     /** 
     * Dagger2 
     */ 
     getAsukabuComponent().inject(this); 
    } 

    @Override 
    public void onUpdateNotifications(Bundle mBundle) { 
     // Handle notifications 

        // show dialog 
        if (dialog != null) dialog.dismiss(); 
        dialog = CustomDialog.getInstance(
          mBundle.getString(KEY_NOTIFICATION_MESSAGE), 
          new CustomDialog.DialogButton(getString(R.string.OK), 
            (dialog1, which) -> { 
            }), new CustomDialog.DialogButton(getString(R.string.cancel), 
            (dialog12, which) -> dialog12.dismiss())); 

        // show 
        dialog.show(getSupportFragmentManager()); 
        break; 
      } 
     } 
    } 

innen BaseActivity.java:

@ActivityScope 
public abstract class BaseActivity extends AppCompatActivity implements BaseView { 

    // I DON'T WANT USE THIS STATIC VAR ANYMORE, TRYING TO GET THIS EXIST COMPONENT IN SERVICE WITHOUT CREATE INSTANCE AGAIN 
    private static Component Component; 

    @Override 
    protected void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // Dagger 2 
    Component = DaggerComponent.builder() 
      .appComponent(MainApplication.getAppComponent(this)).build(); 
    } 

    public static Component getComponent() { 
     return Component; 
    } 
} 

innen Component.java:

@ActivityScope 
@Component(dependencies = {AppComponent.class}) 
public interface Component { 
// Services 
void inject(FirebaseIDService service); 
void inject(FirebaseMsgService service); 
} 

innen AppComponent.java:

@Singleton 
@Component(modules = {AppModule.class}) 
public interface AppComponent { 
    // Get FCM API 
    FCMApi getFCMApi(); 

    // Get Shared Pref. 
    PreferenceStore getPreferenceStore(); 

    Context context(); 
} 

innen AppModule.java:

@Module 
public class AppModule { 

    private Application mApplication; 

    public AppModule(Application application) { 
     mApplication = application; 
    } 

    @Singleton 
    @Provides 
    Context provideContext() { 
     return mApplication.getApplicationContext(); 
    } 

    @Provides 
    @Singleton 
    Application providesApplication() { 
     return mApplication; 
    } 

    @Singleton 
    @Provides 
    SharedPreferences provideSharedPreferences(Context context) { 
     return context.getSharedPreferences(PREF, Context.MODE_PRIVATE); 
    } 

    @Singleton 
    @Provides 
    SharedPreferences.Editor provideSharedPreferencesEditor(SharedPreferences sharedPreferences) { 
     return sharedPreferences.edit(); 
    } 

} 

UPDATE: Nach der Antwort von Alex versucht. Es ist nicht richtig für meinen Fall.

Eigentlich mein Fall:

Ich mag BaseActivityComponent Objekt erhalten. Leute haben die andere Idee?

+0

Der richtige Platz für 'inject()' in einem 'Service' ist' onCreate() ', nicht wahr? –

+0

@DavidRawson: Völlig richtig. –

Antwort

0

Sie können Sie Komponente in Application und Zugriff speichern Sie es überall Schnittstellen und Gießen mit:

Beispiel:

public interface HasComponent<T> { 
    T getComponent(); 
} 

public class MainApplication extends Application implements HasComponent<AppComponent> { 

    //your code, then 
    @Override 
    public AppComponent getComponent() { 
     return this.appComponent; 
    } 
} 

Innerhalb der Service, Anwendungskontext erhalten und es auf diese Schnittstelle wie diese Stimmen:

((HasComponent<AppComponent>) getApplication()).getComponent(); 
+0

Eigentlich arbeite ich so mit 'MainApplication'. Aber in meinem Fall möchte ich ein 'Component' Objekt in 'BaseActivity' (Zeile' private static Component Component; ') bekommen. Ich habe versucht, das gleiche zu tun, aber sieht anders aus. Haben Sie die andere Idee? –

Verwandte Themen