2016-10-01 70 views
0

我想問一下MVP和匕首的工作方式。所以,在android開發中,我們知道Activity和fragment是一個視圖,我們通過實現觀察者(在我的情況下,即使用rxjava +改進)來製作演示者。在這種情況下,我用匕首注入Rest服務(Network Component - > retrofit)。Dagger2:將Api模塊注入演示者(MVP)

我仍然混淆爲我的演示者注入Rest服務,因爲我發現的所有示例都是注入活動。

這是我的代碼。

由於視圖:

public class PageFragment extends Fragment implements ScheduleViewInterface{ 
private ScheduleCursorAdapter scheduleAdapter; 
@Inject RestApi restApiInject; 
private SchedulePresenter mPresenterJson; 

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

    App.getApiComponent(getActivity()).inject(this); 
    mPresenterJson.fetchSchedule(); 
} 

@Override 
public Observable<ScheduleList> getSchedule() { 
    return restApiInject.getScheduleListByUrl("url here"); 
} 

隨着主持人:

public class SchedulePresenter implements Observer<ScheduleList> { 
private ScheduleViewInterface mInterface; 

public SchedulePresenter(ScheduleViewInterface viewInterface){ 
    mInterface = viewInterface; 
} 

@Override 
public void onCompleted() { 
    mInterface.jsonCompleted(); 
} 

@Override 
public void onError(Throwable e) { 
    mInterface.jsonError(e.getMessage()); 
} 

@Override 
public void onNext(ScheduleList scheduleList) { 
    mInterface.jsonScheduleList(scheduleList); 
} 

public void fetchSchedules(){ 
    unSubscribeAll(); 
    subscribe(mInterface.getSchedule(), SchedulePresenter.this); 
} 

,這是我dagger2代碼

@CustomScope 
@Component(modules = ApiModule.class, dependencies = NetworkComponent.class) 
public interface ApiComponent { 
MainActivity inject(MainActivity activity); 
PageFragment inject(PageFragment fragment); 
} 

Architecture pattern

+0

下面是一個示例。 https://github.com/anupcowkur/MVPSample。 – Raghunandan

+0

我很確定你的問題的答案在於[David Medenjak](http://stackoverflow.com/questions/35605408/dagger-2-injection-in-non-activity-java-class) –

回答

0

最好的做法是創建一個Interactor類來處理這個問題,然後在演示者中注入該交互者。看看我的代碼在我的項目下面瞭解。主持人代碼:

public class PopularMoviesPresenterImpl implements PopularMoviesPresenter { 

@Inject 
public PopularMoviesInteractor interactor; 

private PopularMoviesView view; 
private Subscription subscription = Subscriptions.empty(); 

@Inject 
public PopularMoviesPresenterImpl() { 
} 

@Override 
public void setView(PopularMoviesView view) { 
    this.view = view; 
} 

@Override 
public void destroy() { 
    if (subscription != null && !subscription.isUnsubscribed()) 
     subscription.unsubscribe(); 

    interactor.onDestroy(); 

    view = null; 
    interactor = null; 
} 

@Override 
public void loadPopularMoviesData(boolean isConnected, int page, int limit) { 

    if (null != view) { 
     view.showProgress(); 
    } 

    subscription = interactor.loadPopularMovies(page, limit).subscribe(movies -> 
      { 
       if (null != view) { 
        view.hideProgress(); 
        view.setPopularMoviesValue(movies); 

        if (!isConnected) 
         view.showOfflineMessage(); 
       } 
      }, 
      throwable -> { 
       if (null != view) { 
        view.hideProgress(); 
       } 

       if (isConnected) { 
        if (null != view) { 
         view.showRetryMessage(); 
        } 
       } else { 
        if (null != view) { 
         view.showOfflineMessage(); 
        } 
       } 
      }); 

}} 

交互件是:

public class PopularMoviesInteractorImpl implements PopularMoviesInteractor { 
private TraktApi api; 
private SchedulerProvider scheduler; 

private ReplaySubject<Movie[]> moviesDataSubject; 
private Subscription moviesSubscription; 

@Inject 
public PopularMoviesInteractorImpl(TraktApi api, SchedulerProvider scheduler) { 
    this.api = api; 
    this.scheduler = scheduler; 
} 

@Override 
public Observable<Movie[]> loadPopularMovies(int page, int limit) { 
    if (moviesSubscription == null || moviesSubscription.isUnsubscribed()) { 
     moviesDataSubject = ReplaySubject.create(); 

     moviesSubscription = api.getPopularMovies(page, limit, Constants.API_EXTENDED_FULL_IMAGES) 
       .subscribeOn(scheduler.backgroundThread()) 
       .observeOn(scheduler.mainThread()) 
       .subscribe(moviesDataSubject); 
    } 

    return moviesDataSubject.asObservable(); 
} 

@Override 
public void onDestroy() { 
    if (moviesSubscription != null && !moviesSubscription.isUnsubscribed()) 
     moviesSubscription.unsubscribe(); 
}} 

交互器接口:

public interface PopularMoviesInteractor { 

Observable<Movie[]> loadPopularMovies(int page, int limit); 

void onDestroy();} 

,並在你的模塊寫入:

@Provides 
public PopularMoviesInteractor provideInteractor(PopularMoviesInteractorImpl interactor) { 
    return interactor;} 

交互器是通過構建提供。ction注射(你可以用簡單的注射,雖然這樣做)

這裏是MVP的一個清晰的例子: http://github.com/mmirhoseini/fyber_mobile_offers

+0

我無法打開你提供的鏈接,如果你介意給我訪問(aunorafiq),請。 即將生病將此標記爲答案,謝謝 – Raffu

+0

https://github.com/mmirhoseini/trakt.tv –

0

我看到,這個問題已經回答了。但是,如果你想要一個關於如何在MVP體系結構中使用依賴注入的清晰示例,我真的建議你檢查這個boilerplate,因爲它完全基於使用Dagger2的DI並且它遵循MVP體系結構。

目前由鍋爐板處理的依賴關係如下:

  • 數據庫的依賴:封裝了所有的數據庫操作。
  • 共享首選項依賴關係:處理共享首選項。
  • 本地文件依賴:它處理文件保存。
  • 分析依賴:涵蓋報告事件到分析後端的所有操作(GA,Segment,FB,Flurry ..)
  • 記錄依賴性:封裝了所有相關的日誌記錄到控制檯
  • 阿比依賴的操作:封裝了所有API相關的操作

依賴注入的力量來真的很方便尤其是對於測試,因爲你可以很容易地將測試環境中的依賴關係切換爲虛擬依賴關係。