7

作爲標題說,我試圖找出哪一個是在片段中注入依賴關係的最佳方法。 我想獨立於外部框架,如RoboGuice等Android片段和依賴注入

現在,以最簡單的方式,我有一個接口,抽象某種邏輯,並從一個活動,我想注入這個實現接口。我知道我必須爲我的片段提供一個默認構造函數,因爲系統可能需要在某個時候重新創建片段,並且創建片段的新實例的常用方法是提供靜態方法來處理創建這個:

public static Fragment newInstance() { 
    final Bundle bundle = new Bundle(); 
    ... 
    final Fragment fragment = new MyFragment(); 
    fragment.setArguments(bundle); 
    return fragment; 
} 

我該如何傳遞我的依賴到片段?我應該讓它實現Parcelable還是Serializable接口,然後將它打包到Bundle中?有沒有其他方法可以實現結果?

謝謝!

回答

0

你爲什麼不抓住你的活動的依賴?

public void onActivityCreated(Bundle b){ 
    super.onActivityCreated(b) 
    DependencyClass c = ((MyActivity)getActivity()).getDependency(); 
} 
+1

如果我不喜歡這個,我會落得片段連接到正確的活動? 我仍然希望片段獨立且可重用。 – TheImplementer

7

一個簡單的解決方案是聲明一個聲明Fragment所需的依賴關係的接口。然後讓片段的上下文實現此接口,並在需要時從上下文輪詢依賴關係。

合同:

public interface MyDependencies { 

    MyDep getDep(); 

} 

活動:

public MyActivity extends Activity implements MyDependencies { 

    @Override 
    public MyDep getDep(){ 
     return createMyDependencyOrGetItFromASingletonOrGetItFromApplication() 
    } 
} 

片段:

public void onActivityCreated(Bundle b){ 
    super.onActivityCreated(b) 

    if (getActivity() instanceOf MyDependencies) { 
     MyDep dep = ((MyDependencies) getActivity).getDep(); 
    } else { 
     throw new RuntimeException("Context does not support the Fragment, implement MyDependencies") 
    } 
} 

因此,實際上,不存在對活性沒有不必要的耦合,因爲合同由下式定義一個界面。

0

如果你不能通過構造函數傳遞依賴關係(如果你需要一個默認的構造函數),並且你不想使用像Dagger或者RoboGuice這樣的依賴注入庫,另一個經典的方法是使用setter以「注入」依賴性。

Fragment MyFragment { 

Depend mDepend; 

.... 


    public void setDepend(Depend depend) { 
     mDepend = depend; 
    } 

} 

然後在您的活動中,您可以在onCreate方法中注入依賴項。

所以像這樣在你的活動:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_map); 
    MapFragment wrapperFragment = new WrapperFragment(); 
    if (savedInstanceState == null) { 
     getFragmentManager().beginTransaction() 
       .add(R.id.map_container, wrapperFragment).commit(); 
    // find the fragment 
    // call the setter 
    } 
} 
+0

這個解決方案的問題在於,當android重新創建片段時,它使用默認的構造函數,並且不會調用set方法,即使它們以前被調用過。 – FacundoJ