使用Dagger 2在Fragment中注入依赖项时出错

时间:2018-04-07 05:19:11

标签: java android android-fragments dependency-injection dagger-2

我正在尝试使用dagger 2在我的应用程序中的片段中注入依赖项

我有以下模块

网络模块

@Module(includes = ContextModule.class)
public class NetworkModule {

    @Provides
    Cache getCacheFile(Context context) {
        File cacheFile = new File(context.getCacheDir(), "okhttp-cache");
        return new Cache(cacheFile, 10 * 1000 * 1000);
    }

    @Provides
    HttpLoggingInterceptor getHttpLoggingInteceptor() {
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        return logging;
    }

    @Provides
    OkHttp3Downloader getOkHttp3Downloader(Context context) {
        return new OkHttp3Downloader(context);
    }

    @Provides
    OkHttpClient getOkHttpClient(HttpLoggingInterceptor interceptor, Cache cache) {
        OkHttpClient okHttpClient = new OkHttpClient();
        okHttpClient.newBuilder().cache(cache)
                .addInterceptor(interceptor)
                .build();
        return okHttpClient;

    }

    @Provides
    Retrofit getRetrofit(OkHttpClient client, GsonConverterFactory gsonConverterFactory, RxJava2CallAdapterFactory callAdapter) {
        return new Retrofit.Builder()
                .addConverterFactory(gsonConverterFactory)
                .addCallAdapterFactory(callAdapter)
                .baseUrl("https://api.themoviedb.org/3/")
                .client(client)
                .build();
    }

    @Provides
    GsonConverterFactory getGsonConverterFactory() {
        return GsonConverterFactory.create();
    }

    @Provides
    RxJava2CallAdapterFactory getRxJavaFactory() {
        return RxJava2CallAdapterFactory.create();
    }

}

ActivityBuilder模块

@Module
public abstract class ActivityBuilder {

    @ContributesAndroidInjector
    abstract NewsListActivity bindMoviesListActivity();

    @ContributesAndroidInjector(modules = NewsListFragmentModule.class)
    abstract NewsListFragment bindNewsListFragment();
}

这是AppComponent

@Component(modules = {AndroidSupportInjectionModule.class, ContextModule.class, ActivityBuilder.class})
public interface AppComponent {

    @Component.Builder
    interface Builder {

        @BindsInstance
        Builder application(Application application);

        AppComponent build();

    }

    void inject(NewsApp app);

}

这是嵌入片段的活动类

class NewsListActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, HasSupportFragmentInjector {

    @Inject
    lateinit var mAndroidInjector: AndroidInjector<Fragment>

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_news_list)
        setSupportActionBar(toolbar)

        val toggle = ActionBarDrawerToggle(
                this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
        drawer_layout.addDrawerListener(toggle)
        toggle.syncState()

        nav_view.setNavigationItemSelectedListener(this)

        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                    .add(R.id.frame_main, NewsListFragment(), "news-list-fragment")
                    .commit()
        }

    }

    override fun supportFragmentInjector(): AndroidInjector<Fragment> {
        return mAndroidInjector
    }

}

最后这是我的片段类

class NewsListFragment : Fragment() {

    lateinit var picasso: Picasso
    @Inject

    lateinit var newsService: NewsService
    @Inject

    lateinit var newsFragmentViewModel: NewsFragmentViewModel

    lateinit var newsListAdapter: NewsListAdapter

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        swipe_layout.setColorSchemeColors(resources.getColor(R.color.orange),resources.getColor(R.color.green),resources.getColor(R.color.blue))

        newsListAdapter = NewsListAdapter(newsItemClickListener, picasso)
        val layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)

        rv_news_top_headlines.layoutManager = layoutManager
        rv_news_top_headlines.setHasFixedSize(true)
        rv_news_top_headlines.adapter = newsListAdapter

        newsFragmentViewModel = ViewModelProviders.of(this).get(NewsFragmentViewModel::class.java)

        swipe_layout.isRefreshing = true

        newsFragmentViewModel.init(newsService)
        loadDataFromApi()

        swipe_layout.setOnRefreshListener {
            loadDataFromApi()
        }

    }

    private fun loadDataFromApi() {
        // Load data from API
    }

    override fun onAttach(context: Context?) {
        AndroidSupportInjection.inject(this)
        super.onAttach(context)
    }

    private val newsItemClickListener = fun(article: Articles) {
        toast(article.title.toString())
    }

}

我按照许多不同的教程来了解如何在Fragments中使用新的AndroidInjection,所以我没有这些教程的链接?

我有什么问题吗?

错误

e: /Users/sriramr/Desktop/android/NewsApp/app/src/main/java/in/sriram/newsapp/di/AppComponent.java:12: error: [dagger.android.AndroidInjector.inject(T)] dagger.android.AndroidInjector<android.support.v4.app.Fragment> cannot be provided without an @Provides- or @Produces-annotated method.
public interface AppComponent {
       ^
      dagger.android.AndroidInjector<android.support.v4.app.Fragment> is injected at
          in.sriram.newsapp.ui.newslist.NewsListActivity.mAndroidInjector
      in.sriram.newsapp.ui.newslist.NewsListActivity is injected at
          dagger.android.AndroidInjector.inject(arg0)

1 个答案:

答案 0 :(得分:0)

尝试在NewsListActivity

中更改以下内容
AndroidInjector<Fragment>

为:

DispatchingAndroidInjector<Fragment>

此外,您还没有发布您的申请类。确保它有以下内容:

class NewsApp : Application(), HasActivityInjector {

    @Inject
    lateinit var activityDispatchingAndroidInjector: DispatchingAndroidInjector<Activity>

    override fun onCreate() {
        super.onCreate()

        DaggerAppComponent.builder()
            .application(this)
            .build()
            .inject(this)
        // some other initialization
    }

    fun activityInjector(): AndroidInjector<Activity>? {
        return activityDispatchingAndroidInjector
    }
}