2016-12-26 71 views
1

BaseFragment類匕首上超類和子類

open class BaseFragment : Fragment() { 

    @Inject lateinit var apiManager: ApiManager 
    @Inject lateinit var eventBus: EventBus 

    override fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
     App.getInstance().component.inject(this) 
    } 

    override fun onStop() { 
     eventBus.unreg(this) 
     super.onStop() 
    } 

    override fun onStart() { 
     super.onStart() 
     eventBus.reg(this) 
    } 
} 

RoomsFragment類

class RoomsFragment : BaseFragment() { 

    @Inject lateinit var roomAdapter: RoomsAdapter 

    override fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
     App.getInstance().component.inject(this) 
    } 

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { 
     return inflater?.inflate(R.layout.fragment_rooms_fragment_new, container, false) 
    } 

    override fun onActivityCreated(savedInstanceState: Bundle?) { 
     super.onActivityCreated(savedInstanceState) 
     recyclerView.adapter = roomAdapter //This line throws null or lateinit property roomAdapter has not been initialized 
    } 
} 

AdapterModule類

@Module(includes = AppModule.class) 
public class AdapterModule { 

    @Provides //App module has EventBus so i included it in Module 
    RoomsAdapter provideRoomsAdapter(EventBus eventBus) { 
     return new RoomsAdapter(eventBus); 
    } 
} 

AppComonent類

@Singleton 
    @Component(modules = {AppModule.class, AdapterModule.class}) 
    public interface ApplicationComponent { 
     void inject(ApiManager apiManager); 
     void inject(BaseFragment baseFragment); 
    } 
注入

正如你可以看到我試圖在超類和子類中注入對象,但它不是按預期工作。 BaseFragment注入對象工作發現但RoomsFragment注入失敗。任何解決方案

修復: 我忘了爲ApplicationComponent中的子類RoomsFragment添加接口。由於它的超類BaseFragment接口存在,因此在編譯時不會引發任何錯誤。

@Singleton 
    @Component(modules = {AppModule.class, AdapterModule.class}) 
    public interface ApplicationComponent { 
     void inject(RoomsFragment roomsFragment); 
     void inject(ApiManager apiManager); 
     void inject(BaseFragment baseFragment); 
    } 
+1

你在組件中定義的RoomsFragment? – Spartan

+0

是的,我沒有..... –

+1

我希望這不是在您的真實代碼App.getInstance()。component.inject(this)在RoomsFragment中進行評論。 – Spartan

回答

0

試試這個:

@Singleton 
     @Component(modules = {AppModule.class, AdapterModule.class}) 
     public interface ApplicationComponent { 
      void inject(ApiManager apiManager); 
      void inject(BaseFragment baseFragment); 
      void inject(RoomsFragment roomsFragment); 
     } 
4

members injection methods@Component文檔中的文檔描述的相關行爲。

看起來你正試圖注入RoomsFragment的成員。通過添加接受RoomsFragment的方法,您將注入RoomsFragment@Inject成員和任何超類型(在本例中爲`BaseFragment)。

在另一方面,如果你調用接受BaseFragment一個成員注射法,你將注入的BaseFragment@Inject成員,但不任何亞型的任何成員。出於這個原因,爲抽象類型定義成員注入方法幾乎不是一個好主意。

在原始問題中,由於所有成員注入方法都被定義爲相互重載,這一事實變得複雜起來。這意味着對於給定類型,您將獲得不同的注入行爲,具體取決於超載如何解決。請參閱Effective Java 2:Item 41瞭解更多關於爲何這些重載易於出錯的背景信息。

還值得一提的是,原代碼樣品中存在用於ApiManager一個成員注入的方法,但該類型噴射作爲一個實例爲BaseFragment。注入成員可以及時解析依賴關係,因此不需要爲組件上的ApiManager定義任何方法。

因此,爲了注入所有的RoomsFragment成員(申報並inhertied),只是定義RoomsFragment一個成員注射法:

@Singleton 
@Component(modules = {AppModule.class, AdapterModule.class}) 
public interface ApplicationComponent { 
    void inject(RoomsFragment roomsFragment); 
}