Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> ระบบ >> Android

การเรียนรู้โปรเจ็กต์ Android หลายไลบรารีอย่างเชี่ยวชาญ:แนวทางปฏิบัติที่ดีที่สุดสำหรับการพัฒนาในพื้นที่และระยะไกล

การเรียนรู้โปรเจ็กต์ Android หลายไลบรารีอย่างเชี่ยวชาญ:แนวทางปฏิบัติที่ดีที่สุดสำหรับการพัฒนาในพื้นที่และระยะไกล

ในบทความนี้ เราจะพูดถึงโครงการหลายไลบรารีใน Android ไม่ใช่เรื่องธรรมดา แต่ก็ไม่ใช่เรื่องที่ไม่ธรรมดาเช่นกัน

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

การเขียนไลบรารี่ของคุณเองใน Android นั้นเรียบร้อย คุณได้รับโอกาสในการเขียนโค้ดที่สามารถช่วยเหลือนักพัฒนารายอื่น (หรือแม้แต่ตัวคุณเอง)

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

แต่จะเกิดอะไรขึ้นหากห้องสมุดของคุณอาศัยห้องสมุดอื่นที่คุณกำลังพัฒนา

หากคุณไม่ทราบ คุณควรทราบว่าห้องสมุด (read aar) ไม่สามารถมีห้องสมุดท้องถิ่นอื่นอยู่ภายในได้ สามารถพึ่งพาไลบรารีจากระยะไกล (ผ่านการพึ่งพา) แต่ไม่สามารถพึ่งพาบางอย่างในเครื่องได้

สิ่งนี้ไม่รองรับใน Android และแม้ว่าวิธีแก้ปัญหาบางอย่างจะเกิดขึ้นในช่วงหลายปีที่ผ่านมา (FatAar) แต่สิ่งเหล่านี้ก็ไม่ได้แก้ปัญหาเสมอไปและไม่ใช่ข้อมูลล่าสุด มีแม้แต่ Google Issue Tracker ที่ขอฟีเจอร์นี้ซึ่งเปิดมาระยะหนึ่งแล้วและได้รับความสนใจอย่างมากจากชุมชน แต่มาระบุกันว่ากำแพงไหนที่เราสามารถพังได้และกำแพงไหนที่เราทำไม่ได้

ลองนึกภาพลำดับชั้นโครงการของคุณมีลักษณะดังนี้:

-- App
|
 -- OuterLib
 |
 --- InnerLib

ดังนั้น เนื่องจาก InnerLib ไม่สามารถเป็นส่วนหนึ่งของโปรเจ็กต์ดั้งเดิมของคุณได้ แล้วมันจะอยู่ที่ไหน และคุณจะสามารถทำงานในพื้นที่ในขณะที่พัฒนาฟีเจอร์ภายใน InnerLib ได้อย่างไร

เราจะตอบคำถามเหล่านี้ในบทความนี้

โมดูลย่อย Git

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

เพื่อตอบคำถามแรกของเราว่า InnerLib สามารถอาศัยอยู่ที่ไหน เรามีหลายทางเลือก:

  1. ทำให้ InnerLib เป็นโมดูลย่อยของโครงการดั้งเดิมของเรา
  2. ทำให้ InnerLib เป็นการพึ่งพาระยะไกลของตัวเอง

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

บ่อยครั้งเกิดขึ้นที่ในขณะที่ทำงานในโครงการหนึ่ง คุณต้องใช้อีกโครงการหนึ่งจากภายในนั้น 👉 บางทีอาจเป็นห้องสมุดที่บุคคลที่สามพัฒนาขึ้นหรือคุณกำลังพัฒนาแยกกันและใช้ในโครงการหลักหลายโครงการ 👈 ปัญหาทั่วไปเกิดขึ้นในสถานการณ์เหล่านี้:คุณต้องการให้ทั้งสองโปรเจ็กต์แยกจากกัน แต่ยังสามารถใช้โปรเจ็กต์จากภายในโปรเจ็กต์อื่นได้

ย่อหน้านี้แสดงให้เราเห็นว่านี่คือกรณีการใช้งานของเราทุกประการ การใช้โมดูลย่อยก็มีข้อดีของมัน รหัสทั้งหมดของคุณรวมอยู่ในที่เดียว จัดการได้ง่าย และพัฒนาได้ง่ายในพื้นที่

แต่โมดูลย่อยก็มีจุดอ่อนอยู่บ้าง ประการหนึ่งคือข้อเท็จจริงที่คุณจะต้องทราบอยู่เสมอว่าโมดูลย่อยของคุณชี้ไปที่สาขาใด ลองนึกภาพสถานการณ์ที่คุณอยู่ใน Release Branch ในที่เก็บหลักของคุณ และโมดูลย่อยของคุณอยู่ใน Feature Branch หากคุณไม่สังเกต แสดงว่าคุณปล่อยโค้ดเวอร์ชันหนึ่งซึ่งมีบางอย่างที่ไม่พร้อมสำหรับการผลิต อ๊ะ

ทีนี้ลองคิดถึงสิ่งนี้ภายในทีมนักพัฒนา ความผิดพลาดโดยประมาทเพียงครั้งเดียวอาจก่อให้เกิดค่าใช้จ่ายสูง

หากตัวเลือกแรกฟังดูเป็นปัญหาสำหรับคุณ การโฮสต์ไลบรารีของคุณในพื้นที่เก็บข้อมูลอื่นคือตัวเลือกที่สองของคุณ การตั้งค่าพื้นที่เก็บข้อมูลค่อนข้างง่าย แต่ตอนนี้คุณทำงานภายในเครื่องอย่างไร

การทำงานในพื้นที่

ตอนนี้เราได้ตั้งค่าโปรเจ็กต์อย่างถูกต้องแล้ว เราน่าจะมีบรรทัดที่คล้ายกับสิ่งนี้ในไฟล์ OuterLib build.gradle:

dependencies {
 implementation 'url_to_remote_inner_lib_repository'
}

เราจะทำให้วงจรการพัฒนามีประสิทธิภาพและง่ายต่อการทำงานได้อย่างไร? หากเราพัฒนาฟีเจอร์บางอย่างใน InnerLib เราจะทดสอบสิ่งต่าง ๆ ใน OuterLib ได้อย่างไร หรือในใบสมัครของเรา?

วิธีแก้ปัญหาหนึ่งที่อาจเกิดขึ้นคือการนำเข้า InnerLib ของเราภายในเครื่องไปยังโปรเจ็กต์ OuterLib ของเรา ในขณะที่มี InnerLib .gitignor ในโปรเจ็กต์ OuterLib ของเรา คุณสามารถทำได้ง่ายๆ โดยคลิกขวาที่ชื่อโปรเจ็กต์ในเมนูด้านซ้ายมือใน Android Studio แล้วไปที่ใหม่ → โมดูล

การเรียนรู้โปรเจ็กต์ Android หลายไลบรารีอย่างเชี่ยวชาญ:แนวทางปฏิบัติที่ดีที่สุดสำหรับการพัฒนาในพื้นที่และระยะไกล วิธีการนำเข้าโมดูล (ขั้นตอนที่ 1)

จากนั้นในหน้าต่างที่เปิดขึ้น คุณสามารถเลือกตัวเลือกนำเข้าที่ด้านซ้ายล่าง:

การเรียนรู้โปรเจ็กต์ Android หลายไลบรารีอย่างเชี่ยวชาญ:แนวทางปฏิบัติที่ดีที่สุดสำหรับการพัฒนาในพื้นที่และระยะไกล วิธีการนำเข้าโมดูล (ขั้นตอนที่ 2)

จนถึงตอนนี้ฟังดูง่ายและเรียบง่าย แต่จะมีประโยชน์อะไร

แต่ละครั้งที่คุณแก้ไขไฟล์ที่เป็นของ InnerLib การเปลี่ยนแปลงจะไม่สะท้อนให้เห็นภายใน InnerLib เนื่องจากไฟล์นั้นถูกละเว้น ดังนั้น การเปลี่ยนแปลงแต่ละรายการที่คุณต้องการทำจะต้องเกิดขึ้นภายใน InnerLib จากนั้นคุณจะต้องนำเข้าอีกครั้งภายใน OuterLib เพื่อดูการเปลี่ยนแปลง

ดูเหมือนจะไม่ถูกต้อง จะต้องมีวิธีที่ดีกว่าในการทำเช่นนี้

เพียงไม่กี่บรรทัดใน settings.gradle ของเรา ไฟล์ เราสามารถตรวจสอบให้แน่ใจว่าไฟล์ของเรายังคงซิงค์อยู่เมื่อเราทำการเปลี่ยนแปลงใน InnerLib

เมื่อเรานำเข้า InnerLib เข้ามาในโปรเจ็กต์ของเรา Android Studio ได้สร้างสำเนาของ InnerLib และแคชไว้ นั่นคือเหตุผลที่เราจำเป็นต้องนำเข้าไลบรารีอีกครั้งสำหรับทุกการเปลี่ยนแปลงที่เราทำภายในไลบรารี เราสามารถบอก Android Studio ได้ว่าจะอ้างอิงไฟล์จากที่ไหนโดยใช้ projectDir คุณลักษณะ

settings.gradle ของเราอาจมีลักษณะดังนี้:

include ':outerLib', ':innerLib', ':app'

หากต้องการอ้างอิง InnerLib ของเราในเครื่อง เราจะต้องเปลี่ยน settings.gradle เป็น:

include ':outerLib', ':innerLib', ':app'
project('innerLib').projectDir = new File('PATH_TO_INNER_LIB')

เมื่อใช้วิธีการนี้ ไฟล์ InnerLib ของเราจะเชื่อมโยงกับไดเร็กทอรีการทำงานของเรา ดังนั้นทุกการเปลี่ยนแปลงที่เราทำจะมีผลทันที

แต่เราต้องการความยืดหยุ่นเมื่อทำงานภายในเครื่องบน OuterLib ด้วย InnerLib เวอร์ชันระยะไกล สิ่งที่เราเขียนไว้ข้างต้นภายในไฟล์ settings.gradle จะอนุญาตให้เราทำงานในพื้นที่เท่านั้น และแน่นอนว่าเราไม่ต้องการผูกมัดสิ่งนั้นเหมือนเดิม

มาเวนท้องถิ่น

หากวิธีการข้างต้นไม่เหมาะกับคุณ ก็มีแนวทางอื่นที่คุณสามารถทำได้ เช่นเดียวกับที่คุณเผยแพร่ห้องสมุดของคุณแบบสาธารณะด้วย maven คุณสามารถทำสิ่งเดียวกันกับ maven ในเครื่องได้ Maven local คือชุดของพื้นที่เก็บข้อมูลที่อยู่ในเครื่องของคุณ

ด้านล่างนี้คือเส้นทางสำหรับ mavenLocal ขึ้นอยู่กับระบบปฏิบัติการของเครื่องของคุณ:

  • Mac → /Users/YOUR_USERNAME/.m2
  • ลินุกซ์ → /home/YOUR_USERNAME/.m2
  • Windows → C:\Users\YOUR_USERNAME.m2

โดยพื้นฐานแล้ว คุณสามารถเผยแพร่ห้องสมุดของคุณภายในเครื่องแล้วลิงก์ไปยังห้องสมุดในโครงการของคุณได้ ด้วยวิธีนี้ เราสามารถเชื่อมโยงโครงการของเรากับ InnerLib ได้

เพื่ออนุญาตการกำหนดค่านี้ในโครงการของเรา เราจำเป็นต้องทำสิ่งต่อไปนี้:

  1. เพิ่ม mavenLocal() เป็นพื้นที่เก็บข้อมูลภายในส่วนคำสั่งของพื้นที่เก็บข้อมูลของเรา ทั้งนี้เพื่อให้โครงการของเราสามารถค้นหาที่เก็บข้อมูลในเครื่องได้
buildscript {
 repositories {
 mavenLocal()
 }
}
...
allprojects { 
 repositories { 
 mavenLocal() 
 }
}
  1. เปลี่ยนบรรทัดการใช้งานของเราภายในส่วนคำสั่งการพึ่งพาของเราเพื่ออ้างอิง InnerLib ของเราราวกับว่าเรากำลังอ้างอิงจากระยะไกล

  2. หากต้องการเผยแพร่ InnerLib ภายในเครื่อง เราจะสร้างไฟล์ชื่อ PublishLocally.gradle ซึ่งจะมีสิ่งต่อไปนี้:

apply plugin: 'maven-publish' 
project.afterEvaluate {
 publishing { 
 publications {
 library(MavenPublication) { 
 setGroupId groupId //your library package
 setArtifactId artifactId 
 version versionName //I.E. 1.0
 artifact bundleDebugAar
 pom.withXml { 
 def dependenciesNode = asNode().appendNode('dependencies')
 def dependencyNode = dependenciesNode.appendNode('dependency')
 dependencyNode.appendNode('groupId', 'your_group_id')
 dependencyNode.appendNode('artifactId', 'your_artificat_id')
 dependencyNode.appendNode('version', 'your_version')
 } 
 }
 }
 }
}
  1. ภายในไฟล์ build.gradle ระดับแอปพลิเคชันของคุณ ให้เพิ่มบรรทัด:
apply from: '/.publishingLocally.gradle

หากตัวเลือกนี้ดูดีเกินกว่าที่จะเป็นจริง แสดงว่ามันใช่ . ในด้านหนึ่ง เราสามารถพัฒนาสิ่งต่าง ๆ ในพื้นที่ได้อย่างราบรื่นเหมือนกับว่าเราทำงานกับห้องสมุดระยะไกล ในทางกลับกัน หากเราทำการเปลี่ยนแปลงใดๆ ภายใน InnerLib ในขณะที่ทำงานอยู่ในเครื่อง จะต้องเผยแพร่ในเครื่องอีกครั้ง แม้ว่างานนี้จะไม่ใช่งานที่มีค่าใช้จ่ายสูง แต่ก็สร้างความจำเป็นในการทำงานที่น่าเบื่อซ้ำแล้วซ้ำอีก

โซลูชันสำหรับการทำงานในพื้นที่และระยะไกล

เราต้องการหลีกเลี่ยงความจำเป็นในการเผยแพร่แพ็คเกจ InnerLib ของเราซ้ำทุกครั้งที่เราทำการเปลี่ยนแปลงในเครื่อง เราจำเป็นต้องหาวิธีที่จะทำให้โครงการของเราตระหนักถึงการเปลี่ยนแปลงเหล่านั้น

ในส่วนการทำงานในพื้นที่ เราพบวิธีดำเนินการดังกล่าวแล้ว แต่เราประสบปัญหาในการคอมมิตไฟล์ settings.gradle เพื่อแก้ไขปัญหานี้เพื่อให้เราสามารถทำงานทั้งในพื้นที่และระยะไกลด้วย InnerLib ของเรา เราจะใช้พารามิเตอร์ที่เราจะกำหนดใน gradle.properties ของเรา ไฟล์.

ไฟล์ gradle.properties เป็นที่ที่คุณสามารถจัดเก็บการตั้งค่าระดับโปรเจ็กต์ที่กำหนดค่าสภาพแวดล้อมการพัฒนาของคุณ สิ่งนี้ช่วยให้แน่ใจว่านักพัฒนาทุกคนในทีมมีสภาพแวดล้อมการพัฒนาที่สอดคล้องกัน

การตั้งค่าบางอย่างที่คุณอาจคุ้นเคยซึ่งพบในไฟล์นี้คือการสนับสนุน AndroidX (android.useAndroidX=true) หรืออาร์กิวเมนต์ JVM (org.gradle.jvmargs=-Xmx1536m)

เพื่อช่วยเราแก้ไขสถานการณ์ของเรา เราสามารถเพิ่มพารามิเตอร์ที่นี่เพื่อระบุว่าเราต้องการทำงานในพื้นที่หรือไม่ บางสิ่งบางอย่างตาม:

workingLocally = false

พารามิเตอร์นี้จะช่วยให้เราแยกแยะระหว่างการตั้งค่าที่เรากำลังทำงานด้วย ทั้งแบบโลคัลหรือด้วยโค้ดที่ใช้งานจริง ขั้นแรก เรามาแก้ไขสิ่งที่เรามีในไฟล์ settings.gradle โดยล้อมมันไว้ในเงื่อนไขที่ตรวจสอบว่าพารามิเตอร์ของเราเป็นจริงหรือไม่:

include ':outerLib', ':innerLib', ':app'
if (workingLocally.booleanValue()) {
 project('innerLib').projectDir = new File('PATH_TO_INNER_LIB')
}

ด้วยวิธีนี้ เราจะแจ้งให้โปรเจ็กต์รับไฟล์สำหรับ InnerLib จากเครื่องของเราภายในเครื่อง

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

dependencies {
 if (workingLocally.booleanValue()) {
 implementation 'innerLib'
 } else {
 implementation 'url_to_remote_repository'
 }
}

⚠️ คำเตือน:คุณไม่ควรคอมมิตไฟล์ gradle.properties เมื่อทำงานในเครื่อง

การเดินทางนั้นยาวนานและอาจดูเหนื่อยมาก แต่ตอนนี้ เรามีการตั้งค่าที่สมบูรณ์แบบสำหรับการทำงานทั้งในพื้นที่และระยะไกลในโครงการห้องสมุดหลายแห่ง

หากคุณพบปัญหาใดๆ หรือต้องการแสดงความคิดเห็น คุณสามารถแสดงความคิดเห็นได้

เรียนรู้การเขียนโค้ดฟรี หลักสูตรโอเพ่นซอร์สของ freeCodeCamp ช่วยให้ผู้คนมากกว่า 40,000 คนได้งานในตำแหน่งนักพัฒนา เริ่มต้น