โยกย้ายจาก Dagger2 ไปยัง Hilt ในโครงการหลายโมดูล

May 10 2023
คำแนะนำทีละขั้นตอนในการโยกย้ายจาก Dagger ไปยัง Hilt ในโครงการหลายโมดูล โครงสร้างโครงการ เพื่อให้เห็นภาพโครงการ ประกอบด้วยโมดูลหลายโมดูล NetworkModule, StorageModule, CommonModule, FeatureModule เป็นต้น

คำแนะนำทีละขั้นตอนในการโยกย้ายจากDaggerไปยังHiltในโครงการหลายโมดูล

ภาพถ่ายโดย Saif71.com บน Unsplash

โครงสร้างโครงการ

เพื่อให้เห็นภาพโครงการ ประกอบด้วยโมดูลหลายโมดูล NetworkModule, StorageModule, CommonModule, FeatureModule เป็นต้น ในโครงการจริงอาจมีโมดูลมากกว่านี้ แต่เราจำกัดเฉพาะโมดูลต่อไปนี้

กลยุทธ์การย้ายถิ่น

เราต้องการโยกย้ายอย่างสมบูรณ์Daggerแต่Hiltในทางปฏิบัติ เราต้องการวิธีการเพิ่มเติม โดยที่เราจะโอนย้ายappโครงการของเราไปHiltที่โมดูลอื่นก่อน ซึ่งหมายความว่าDaggerและHiltควรทำงานควบคู่กันไปสักระยะหนึ่งจนกว่าการย้ายข้อมูลจะเสร็จสิ้น

รุ่น

เรื่องราว นี้จะทำการโยกย้ายจากDagger 2.24ถึงHilt 2.45

เนื้อหา

  • การกำหนดค่า/การเตรียมการ
  • ย้ายข้อมูลส่วนประกอบของแอปและ Singleton
  • ย้ายคลาสแอปพลิเคชัน
  • ย้ายคลาสกิจกรรม
  • โยกย้ายชิ้นส่วน
  • โยกย้าย ViewModel
  • การล้างข้อมูลหลังการย้ายข้อมูล
  • บทสรุปและประเด็นสำคัญ

ในการรวม เพิ่มการอ้างอิงต่อไปนี้ลงใน ไฟล์Hiltของแอป Gradlebuild.gradle

กำหนดค่า เพื่อตั้ง ค่าkaptCorrectErrorType เป็นtrueไฟล์build.gradle

dependencies {
  implementation 'com.google.dagger:hilt-android:2.45'
  kapt 'com.google.dagger:hilt-compiler:2.45'
}
// Allow references to generated code
kapt {
    correctErrorTypes = true
}

plugins {
    // other plugins
    id 'com.google.dagger.hilt.android' version '2.45' apply false
}

plugins {
    // other plugins
    id 'com.google.dagger.hilt.android'
}
android {
    ....
}

ย้ายส่วนประกอบแอป

Dagger มีSingleton Componentโมดูล Dagger ทั้งหมดที่สร้างขึ้นในแอปหรือโมดูลอื่นๆ ของโครงการ และโดยปกติจะทำในAppComponentคลาสที่สร้างขึ้นDaggerสำหรับ

ลองดูที่ไฟล์AppComponent.kt ปัจจุบัน

ในการโอนย้ายSingleton Componentเราจำเป็นต้องติดตั้งแต่ละโมดูล เช่นNetworkModule , StorageModuleฯลฯ ลงในSingletonComponentfor Hiltคุณสามารถทำได้โดยใส่คำอธิบายประกอบโมดูลแต่ละโมดูลด้วย@InstallIn(SingletonComponent::class)แต่ถ้าคุณมีโมดูลจำนวนมาก การเปลี่ยนโมดูลทั้งหมดในคราวเดียวอาจไม่ใช่ความคิดที่ดี แต่คุณทำได้ สร้างAggregatedModuleซึ่งจะมีคำอธิบายประกอบ และรวม โมดูล@InstallIn(SingletonComponent::class)เหล่านี้ทั้งหมด ที่มีคำอธิบาย ประกอบด้วยDagger@Module(includes = [ <all of these modules > ])

เรียกใช้โครงการ มันจะขึ้นข้อผิดพลาด

ข้อผิดพลาด DisableModuleHasInstallInCheck

หลังจากที่คุณเรียกใช้โครงการHiltจะพยายามค้นหา คำ อธิบาย@InstallInประกอบสำหรับแต่ละโมดูลซึ่งรวมอยู่ในAggregatedModuleคำอธิบายประกอบด้วย จะทำให้เกิดข้อผิดพลาดหากพบโมดูลที่ไม่ได้ใส่คำอธิบายประกอบเนื่องจากเราไม่ได้ใส่คำอธิบายประกอบทุกโมดูลด้วยเนื่องจากเราอยู่ระหว่างการย้ายข้อมูล เราสามารถปิดใช้งานข้อผิดพลาดนี้โดยใช้แฟล็กต่อไปนี้@ModuleHilt@Install@InstallIn

-Adagger.hilt.disableModulesHaveInstallInCheck=true.

คุณสามารถระบุในระดับแอปbuild.gradleได้ด้านล่าง แต่เราควรนำธงนี้ออกเมื่อการย้ายข้อมูลทั้งหมดเสร็จสิ้น

defaultConfig {
   
    //TODO: remove this after migration to Hilt
    javaCompileOptions {
        annotationProcessorOptions {
            arguments["dagger.hilt.disableModulesHaveInstallInCheck"]="true"
        }
    }
}

ย้ายคลาสแอปพลิเคชัน

หากต้องการเพิ่ม Hilt ลงในแอปพลิเคชัน ให้ใส่คำอธิบายประกอบในApplicationชั้นเรียนด้วย@HiltAndroidApp. คุณควรลบ@Componentและ@Component.Builderที่มีอยู่ในAppComponentชั้นเรียนตามที่กล่าวไว้ข้างต้น

หากคุณApplicationขยายจากDaggerApplicationหรือนำไปใช้HasAndroidInjectorคุณยังคงต้องเก็บรหัสบางส่วนไว้ด้านล่างในทั้งสองกรณีนี้ เพื่อรองรับทั้งสองDaggerอย่างHiltควบคู่กันไปจนกว่าการย้ายข้อมูลทั้งหมดจะเสร็จสมบูรณ์

หากคุณApplicationขยายจากDaggerApplicationคลาสแอปพลิเคชันของคุณจะมีลักษณะดังนี้

และถ้าคุณApplicationนำไปใช้งานHasAndroidInjectorของคุณ แอปพลิเคชันของคุณต้องมีลักษณะดังนี้

เมื่อการย้ายข้อมูลทั้งหมดเสร็จสิ้น คุณจะต้องลบรหัสดังกล่าวออกจากApplicationชั้นเรียนของคุณ และApplicationจะมีลักษณะดังนี้ (แต่นั่นจะเป็นหนึ่งในขั้นตอนสุดท้าย โปรดอย่าทำตอนนี้)

เรียกใช้โครงการ ควรสร้างโครงการของคุณสำเร็จและแอปต้องเปิดโดยไม่มีข้อยกเว้นเวลาทำงาน

ย้ายระดับกิจกรรม

Dagger จัดให้@ContributesAndroidInjectorมีการระบุกิจกรรม/ส่วนย่อยใด ๆ เป็นผู้มีส่วนร่วมสำหรับ Android Injector ในโครงการของเราที่ทำในMainActivityModule, หนึ่งในโมดูลที่รวมอยู่ในAggregatedModule

MainActivityModuleลักษณะเช่นนี้ก่อนการย้ายข้อมูล

MainActivityลักษณะเช่นนี้ก่อนการย้ายข้อมูล

ในการย้ายข้อมูลของเราMainActivityไปที่HiltเราจะกำจัดMainActivityModuleโมดูลคลาสทั้งหมดและเพิ่มคำอธิบายประกอบ@AndroidEntryPointสำหรับ MainActivityเนื่องจากเราMainActivityกำลังขยายจากDaggerAppCompatActivityเราจำเป็นต้องขยายกิจกรรมของเราจากที่สอดคล้องกันAppCompatActivityดังนั้นหลังจากการย้ายข้อมูลของเราMainActivityจะมีลักษณะดังนี้

ดำเนินโครงการของคุณ ควรจะประสบความสำเร็จด้วยMainActivityการย้ายข้อมูลไปยังHilt

ย้ายส่วน/มุมมอง/ตัวรับการออกอากาศ

การย้าย Fragment ใดๆ เข้าไปHiltจะทำด้วยขั้นตอนเดียวกับที่เราทำในการย้ายไปMainActivityยัง Hilt ขั้นตอนอยู่ด้านล่าง

  1. ลบโค้ดที่คุณใส่คำอธิบายประกอบ Fragment ซึ่ง@ContributesAndroidInjectorน่าจะเป็นโมดูล
  2. ลบโมดูลที่SingletonComponentจัดการ@ContributesAndroidInjectorกับ Fragment ของคุณ
  3. ใส่คำอธิบายประกอบส่วนของคุณด้วย@AndroidEntryPoint
  4. หากแฟรกเมนต์ของคุณถูกขยายจากDaggerFragmentนั้นคุณจำเป็นต้องขยายแฟรกเมนต์จากFragmentคลาส

โยกย้าย ViewModel

การโอนย้าย ViewModel ต้องมีขั้นตอนบางอย่าง

ก่อนอื่นให้ใส่คำอธิบายประกอบ viewModel ของคุณด้วย@HiltViewModel

ในการFeatureViewModelแทรกเข้าไปHiltเราจะใช้ส่วนขยายแฟรกเมนต์viewModels()ที่มีให้ในการพึ่งพาส่วนขยายแฟรกเมนต์ที่เราจะเพิ่มในbuild.gradleไฟล์ที่เกี่ยวข้องดังต่อไปนี้

implementation "androidx.fragment:fragment-ktx:1.5.6"

ตอนนี้ลบที่เกี่ยวข้อง@Bindและ@IntoMapการ@ViewModelKeyผูกที่FeatureViewModelเราใช้สำหรับกริช

ในกริชที่จะฉีด ViewModel เรายังมีlateinit varคุณสมบัติซึ่งจะอยู่ที่injectedรันไทม์โดยใช้บางส่วนViewModelFactoryที่ไม่จำเป็นอีกต่อไป ดังนั้นคุณสามารถลบและโค้ดที่เกี่ยวข้องได้หากไม่มี ViewModel/Fragment อื่นที่ยังอยู่บนกริชViewModelModuleViewModelProviderFactory

ดำเนินโครงการของคุณ ควรจะประสบความสำเร็จด้วยFragment and ViewModelการย้ายข้อมูลไปยังHilt

โยกย้ายโมดูลอื่น ๆ

จนถึงตอนนี้เรากำลังย้ายComponents/ Modules/ Activity/ Fragmentในโมดูลแอป แต่เราต้องโอนย้ายโมดูลอื่นๆ ในตอนนี้ เราจะไปทีละโมดูลและย้ายทั้งหมดไปที่ Hilt โดยใช้ขั้นตอนต่อไปนี้

  1. เพิ่มHiltการอ้างอิงในbuild.gradleไฟล์ของโมดูล
  2. อธิบายแต่ละรายการ@Moduleด้วย@InstallInคำอธิบายประกอบ
  3. ลบ@JvmStaticคำอธิบายประกอบสำหรับแต่ละ@Provideคำอธิบายประกอบ ถ้าคุณมี เนื่องจากไม่จำเป็นอีกต่อไปในHilt
  4. ใส่คำอธิบายประกอบของคุณFragment/ Activityด้วย@AndroidEntryPointและลบที่เกี่ยวข้อง@ContributesAndroidInjector
  5. โอนย้าย ViewModels ของคุณที่มีคำอธิบายประกอบ@HiltViewModelและใช้ส่วนขยายส่วนย่อยviewModels()เพื่อใส่โมเดลมุมมองเหล่านั้น
  6. ทำการลบโมดูลเหล่านั้นทั้งหมดต่อไปซึ่งจะไม่ต้องการอีกต่อไปในAggregatedModule. AggregatedModule เราสร้างข้างต้นในขั้นตอนแรกของเรา

เมื่อแต่ละโมดูลโครงการถูกย้ายไปยังHilt. ต้องใช้เวลาทำความสะอาด

  1. ลบ enableModuleInstallInCheck = true ที่เราเพิ่มเมื่อเริ่มต้นในระดับแอพหรืออื่น ๆbuild.gradleและลบ@DisableInstallInCheckคำอธิบายประกอบหากมีการเพิ่มลงไป@Module
  2. defaultConfig {
       
        //TODO: remove this after migration to Hilt
        javaCompileOptions {
            annotationProcessorOptions {
                arguments["dagger.hilt.disableModulesHaveInstallInCheck"]="true"
            }
        }
    }
    

4. ลบDaggerการอ้างอิงทั้งหมดในโมดูลทั้งหมดของคุณ

รันโปรเจกต์ของคุณ มันควรจะรันโปรเจกต์ของคุณสำเร็จโดยโอนย้ายไปยังHilt

บทสรุปและประเด็นสำคัญ

ภาพรวมระดับสูงของการเปลี่ยนแปลงรหัสหลังการย้ายจะมีลักษณะดังนี้

  1. คำอธิบายประกอบโค้ดทั้งหมด@Component/ @Component.Builder/ @Component.Factory/ @ContributesAndroidInjector/ @ViewModelKeyจะถูกลบออก
  2. ViewModels ทั้งหมดของคุณจะต้องใส่คำอธิบายประกอบ@HiltViewModel
  3. @Moduleคลาสทั้งหมด จะต้องมี @InstallInคำอธิบายประกอบพร้อมคำอธิบายประกอบ
  4. แฟรกเมนต์/กิจกรรม/มุมมอง/บริการจะต้องมีคำอธิบายประกอบ@AndroidEntryPoint
  5. คลาสแอ็พพลิเคชันต้องมีคำอธิบายประกอบ@HiltAndroidApp
  6. AppComponentและรหัสที่เกี่ยวข้องจะต้องถูกลบออก
  7. @JvmStaticคำอธิบายประกอบภายในโมดูล Hilt จะต้องไม่มีอยู่อีกต่อไป
  • การพึ่งพาการฉีดโดยใช้ Hilt
  • โยกย้ายไปยังเอกสารอย่างเป็นทางการของ Hilt

อย่าลืมติดตามและถ้าคุณชอบ :)

— — — — — — — — — — —

GitHub | LinkedIn | ทวิตเตอร์

เพิ่มระดับการเข้ารหัส

ขอบคุณที่เป็นส่วนหนึ่งของชุมชนของเรา! ก่อนที่คุณจะไป:

  • ปรบมือให้กับเรื่องราวและติดตามผู้เขียน
  • ดูเนื้อหาเพิ่มเติมในสิ่งพิมพ์ Level Up Coding
  • หลักสูตรสัมภาษณ์การเข้ารหัสฟรี ⇒ ดูหลักสูตร
  • ติดตามเรา: Twitter | LinkedIn | จดหมายข่าว