web-dev-qa-db-fra.com

Erreur Kotlin: Dagger ne supporte pas l'injection dans des champs privés

J'utilise dans l'activité de kotlin ViewPager et je veux dans Kotlin Fragment utiliser l'injection de poignard. J'ai l'erreur: Dagger ne supporte pas l'injection dans les champs privés. Dans Java Fragmentez le travail d'injection de poignard. Pourquoi ne puis-je pas injecter de poignard dans kotlin faragment?

dans mon activité de kotlin

mPagerAdapter = object : FragmentPagerAdapter(supportFragmentManager) {

        private val mFragments = arrayOf(KotlinFragment(), JavaFragment())
        private val mFragmentNames = arrayOf(getString(R.string.cashdocuments), getString(R.string.action_absmysql))

        override fun getItem(position: Int): Fragment {
            return mFragments[position]
        }

        override fun getCount(): Int {
            return mFragments.size
        }

        override fun getPageTitle(position: Int): CharSequence {
            return mFragmentNames[position]
        }
    }

mon fragment de kotlin

class KotlinFragment : Fragment()  {


@Inject
internal var mSharedPreferences: SharedPreferences? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    (activity.application as SamfantozziApp).dgaeacomponent().inject(this)

}

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    super.onCreateView(inflater, container, savedInstanceState)
    val rootView = inflater!!.inflate(R.layout.activity_absserver, container, false)

    return rootView
}

}

messages gradle construire

enter image description here

30
eurosecom

Je suis arrivé par hasard à ma propre réponse et je dois avouer que cela ne fonctionne pas (du moins pour mon cas d'utilisation). Veuillez considérer réponse d'Avilio qui a également fonctionné pour moi: remplacez internal par lateinit.


Ancienne réponse

Supprimez le modificateur internal. La dague a besoin d'au moins un accès privé au paquet pour pouvoir accéder au champ annoté. En Kotlin, internal modificateur n'est pas une substitution du modificateur d'accès Java de paquet privé.

Pour une explication détaillée des différences entre les modificateurs dans Java et Kotlin se rapportent au podcast fragmenté épisode # 101 - "Learning Kotlin - modificateurs de visibilité, modificateur interne, modules ", ainsi que le document officiel .

42
azizbekian

Vous avez une erreur ici:

    @Inject
internal var mSharedPreferences: SharedPreferences? = null

On dirait que vous avez ajouté l'annotation @Inject À la classe KotlinFragment

S'il vous plaît le changer en ceci et cela fonctionnera:

var mSharedPreferences: SharedPreferences? = null
        @Inject set

Voici le lien vers la documentation: https://kotlinlang.org/docs/reference/annotations.html

36
Danylo Volokh

J'ai eu la même erreur, même après la suppression du mot clé interne. J'ai donc remplacé interne par lateinit et cela a fonctionné.

26
Avilio

Aussi simple que vous pouvez le faire, changez cette ligne

@Inject
internal var mSharedPreferences: SharedPreferences? = null

À

@set:Inject
internal var mSharedPreferences: SharedPreferences? = null

cela fonctionne comme un charme dans mon cas.

13
Hemant Parmar
@Inject
lateinit var mSharedPreferences: SharedPreferences

En outre, cela a fonctionné pour moi aussi bien pour la variable d'initialisation tardive

4
0xAliHn

Avez-vous défini fun inject(fragment: KotlinFragment) dans votre ApplicationComponent? Parce que votre message d'erreur semble indiquer exactement cela.

EDIT: peut-être que vous n'avez pas fourni SharedPreferences dans votre module comme ceci:

@Module
public class AndroidModule {
    private final TimrApplication application;

    public AndroidModule(TimrApplication application) {
        this.application = application;
    }

    @Provides
    SharedPreferences provideSharedPreferences(){
        return PreferenceManager.getDefaultSharedPreferences(application);
    }
}
2
finki

Supprimez le modificateur internal. Et je devais aussi déclarer lateinit et supprimer l’option facultative.

2
Federico Heiland