2016-11-21 9 views
0

を経由して私がプレゼンター、BaseTopPresenterのインスタンスを取得するために、私は、プロパティ注射を介してActivity & Fragmentで本当によく働くことができるダガー2を注入既存のMVPプレゼンターDagger2

使用してMVP構造で働いています。

私の問題は、私はコンポーネントを取得し、プレゼンターBaseTopPresenterを取得するためにinject()を呼び出すためのアクティビティ内の静的メソッドgetComponent()を得ることなくサービスFirebaseMsgServiceに私のプレゼンターBaseTopPresenter presenter;を注入する必要があります。

p/s:私はからのUI更新を行うためにLocalBroadcastReceiverを使用することを考えましたが、私はMVPをやろうとしています。 Serviceの中にプレゼンターのインスタンスを得るためのエレガントな方法を提供することによって私を助けてください。私は多くのユースケースを持っています。 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(); 
    } 
    } 

FirebaseMsgService.java内側:CustomizeNotifications.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()); 
    } 

} 

:BaseTopPresenter.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); 
    }); 
} 
} 

BaseTopActivity.java内部
@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); 
    } 
} 

@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; 
      } 
     } 
    } 

BaseActivity.java内側:Component.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; 
    } 
} 

:AppComponent.java内部

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

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:アレックスの答えを試みた後。私の場合は正しくありません。実際

、私の場合:

私はBaseActivityComponentオブジェクトを取得したいです。人々には別のアイデアがありますか?あなたのサービス内

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

public class MainApplication extends Application implements HasComponent<AppComponent> { 

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

、アプリケーション・コンテキストを取得し、このようにそのインターフェイスにキャスト:

+0

'サービス '内の' inject() 'の正しい場所は' onCreate() 'です。 –

+0

@DavidRawson:完全に正しい。 –

答えて

0

あなたはインタフェースやキャストを使用してApplication、どこでもアクセスして、コンポーネントあなたを保存することができます。

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

実際には、この方法は 'MainApplication'で動作します。しかし私の場合は、 'BaseActivity'(' private static Component Component; ')に' Component'オブジェクトを入れたいです。私は同じことをしようとしましたが、異なっているように見えます。他のアイデアはありますか? –

関連する問題