วิธีการนำ Android Library ที่เขียนขึ้น jcenter และ Maven Central ผ่าน Android Studio ให้คนอื่นนำไปใช้งาน

Posted on 31 May 2015 17:18 | 7178 reads | 0 shares
 

ใน Android Studio หากคุณต้องการจะใช้ Library อะไร ก็เพียงใส่ dependency สั้นๆลงไปในไฟล์ build.gradle จากนั้นบู้มมมม แอพฯของคุณก็มี Library นั้นๆใช้แล้ว

dependencies {
    compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
}

อาจจะสงสัยว่าเจ้า Android Studio มันไปหา Library มาจากไหน ไปกลั่นมาจากละอองน้ำในอากาศหรืออย่างไร วันนี้จะมาเข้าใจระบบตรงนี้กันทั้งระบบครับ รวมถึงจะพาไปรู้จักวิธีเอา Library ที่เราเขียนเองแชร์ขึ้นไปให้คนอื่นเอาไปใช้ด้วยวิธีที่เขียนด้านบนนี้อีกด้วย นอกจากจะประโยชน์ต่อโลกมนุษย์แล้วยังจะเท่อย่าบอกใครอีกตะหากนะ !

Android Studio ไปโหลดไลบรารี่มาจากไหน?

คำถามแรกที่เชื่อว่าหลายๆคนยังคงสงสัยว่าทำไมใส่แค่บรรทัดเดียวแล้วถึงได้ Library มาเลย มันไป Search Google แล้วเอามาแปะให้หรือ?

จริงๆแล้ววิธีมันค่อนข้างตรงไปตรงมาครับ มันจะวิ่งไปหา Library มาจาก Maven Repository Server ที่เรากำหนด(ไปโดยไม่รู้ตัว)นั่นเอง (Apache Maven คือ Server สำหรับเก็บ Library ที่พัฒนาโดย Apache และสามารถกดเข้าไปดูได้เหมือน File Server) โดยหลักๆ Maven Repository มาตรฐานที่ใช้โค้ดแอนดรอยด์กันจะมีอยู่ 2 ที่ ได้แก่ jcenter และ Maven Central

jcenter

เป็น Repository ที่ Host โดย bintray.com สามารถกดเข้าไปดู Repository ทั้งอันได้ที่ Bintray

การจะใช้ jcenter ในโปรเจค ต้องใส่สคริปต์ดังนี้ลงไฟล์ build.gradle ของโปรเจค

allprojects {
    repositories {
        jcenter()
    }
}

Maven Central

เป็น Repository ที่ Host โดย sonatype.org สามารถกดเข้าไปดู Repository ทั้งอันได้ที่ Sonatype

การจะใช้ Maven Central ในโปรเจค ต้องใส่สคริปต์ดังนี้ลงไฟล์ build.gradle ของโปรเจค

allprojects {
    repositories {
        mavenCentral()
    }
}

ซึ่งทั้ง jcenter และ Maven Central เป็น Server คนละที่กันอย่างสิ้นเชิง สิ่งที่มีใน jcenter อาจจะไม่มีใน Maven Central หรือในทางตรงกันข้ามก็เช่นเดียวกัน

นอกจากนั้นใช้ Server มาตรฐานแล้ว เรายังสามารถกำหนด Maven Repository Server เองได้ ในกรณีที่ไปใช้ Library ของคนอินดี้ที่ไม่อยากวาง Library ไว้รวมกันคนอื่น ... ยกตัวอย่างเช่น Fabric.io ของ Twitter ก็มี Maven Repository ของตัวเองอยู่ที่ https://maven.fabric.io/public เป็นต้น ในกรณีนี้เราสามารถกำหนด URL เองด้วยวิธีนี้

repositories {
    maven { url 'https://maven.fabric.io/public' }
}

หลังจากนั้นเราก็จะสามารถเข้าถึง Library ที่อยู่ด้านใน Server ตัวนี้ได้ด้วยวิธีปกติ

dependencies {
    compile 'com.crashlytics.sdk.android:crashlytics:[email protected]'
}

แต่ถามว่าแบบไหนดีกว่า? แน่นอนว่าการใช้ไลบรารี่ใน jcenter หรือ Maven Central ต้องสะดวกที่สุดเพราะผู้ใช้ไม่ต้องมานั่งกำหนด URL ของ Maven Repository เอง แค่ใส่บรรทัดที่กำหนดไปบรรทัดเดียวก็ควรใช้งานได้เลย ดังนั้นในบทความนี้เราจะเน้นไปที่ jcenter และ Maven Central กันครับ

Note เพิ่มนิดหน่อยว่าจริงๆนอกจาก Maven Repository แล้ว เราสามารถใช้ร่วมกับ Ivy Repository ได้เช่นกัน แต่เนื่องจากตั้งแต่เขียนมายังไม่เคยมีโอกาสได้ใช้ Ivy เลยแม้แต่ครั้งเดียว (รวมถึงไม่เห็นใครใช้ด้วย) ดังนั้นเลยขอไม่พูดถึงในบทความนี้นะครับ เน้นไปทาง Maven ที่ใช้งานจริงตลอดเวลากันดีกว่า =)

เข้าใจ jcenter และ Maven Central

สงสัยมั้ยว่าทำไมถึงมี Repository มาตรฐานถึง 2 ที่ ทำไมไม่มีที่เดียวไปเลย?

จริงๆแล้วเรื่องมันมีอยู่ว่าทั้งสองเจ้าเป็นผู้ให้บริการคนละเจ้ากัน แต่ทั้งสองที่ทำหน้าที่เดียวกันคือ Host Repository ให้ ดังนั้นก็แล้วแต่นักพัฒนาว่าจะเอาไลบรารี่ขึ้นไปไว้ที่ไหน

ซึ่งแต่ก่อน Android Studio เลือกใช้ Maven Central เป็นหลัก ตอน New Project มาก็จะใช้ mavenCentral() เป็น Default ทุกคนก็เลยเฮกันไปอัพขึ้น Maven Central เป็นหลัก

แต่ Maven Central ไม่ Developer Friendly เท่าไหร่ เอาไลบรารี่ขึ้นก็ยาก เรียกว่าต้อง Geek ถึงขั้นหนึ่งเลยถึงจะทำได้ รวมถึงมี Security Concern อยู่หลายเรื่อง จนสุดท้ายต้นปีที่ผ่านมา ผู้พัฒนา Android Studio ก็ตัดสินใจสลับ Default Repository จาก Maven Central ไปใช้ jcenter แทน และนี่เป็นสาเหตุให้ถ้า New Project ด้วย Android Studio เวอร์ชั่นใหม่ๆ ก็จะขึ้นเป็น jcenter() แทน mavenCentral() นั่นเอง

เหตุผลหลักๆที่กูเกิ้ลสลับ Repository หลักจาก Maven Central มาเป็น jcenter มีดังนี้

- jcenter กระจายไลบรารี่ผ่าน CDN ทำให้ทุกคนเข้าถึงได้เร็วกว่าไม่ว่าจะอยู่ส่วนไหนของโลก

- jcenter เป็น Java Repository ที่ใหญ่ที่สุดในโลก ดังนั้นอะไรก็ตามที่มีอยู่บน Maven Central เค้าแทบจะเคลมว่าจะมีอยู่บน jcenter ด้วยแน่นอนเลยทีเดียว หรือพูดง่ายๆคือ jcenter เป็น superset ของ Maven Central ครับ

- การอัพโหลดไลบรารี่ของเราเองขึ้น Repository ทำได้ง่ายมาก อัพโหลดขึ้นได้ตรงๆเลย แต่ Maven Central ต้อง Sign ก่อนถึงจะเอาขึ้นได้

- UI Friendly กว่า Maven Central มาก

- หากอยากอัพโหลดไลบรารี่ขึ้น Maven Central ด้วย jcenter ก็จัดฟีเจอร์เด็ดให้เรียบร้อย สามารถจิ้มคลิกเดียวผ่านหน้าเว็บ bintray แล้วไลบรารี่จะไปสิงสถิตย์อยู่บน Maven Central ทันที!

ซึ่งจากเหตุผลทั้งหมดที่ยกมาและจากประสบการณ์ที่ได้ลองด้วยตัวเองแล้วทั้ง jcenter และ Maven Central ต้องบอกเลยว่าการย้าย Default Repository ไปเป็น jcenter เป็นการตัดสินใจที่ถูกต้องเป็นอย่างมาก

ดังนั้นจากนี้ทางเราแนะนำให้อัพโหลดไลบรารี่ขึ้นทั้งบน jcenter และ Maven Central แต่กระบวนการให้โฟกัสไปที่ jcenter อย่างเดียวเลยครับ เพราะเมื่อเราอัพขึ้น jcenter ได้แล้ว การเอาขึ้น Maven Central ก็จะทำได้ง่ายมากแค่เพียงคลิกเดียวเท่านั้นเอง

ขั้นตอนเบื้องหลังการดึงไลบรารี่จาก Repository

ก่อนจะไปถึงเรื่องการเอา Library ขึ้น jcenter เรามาทำความเข้าใจก่อนว่าตอนเราพิมพ์เข้าไปว่า

compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'

แล้วมันไปใช้กระบวนการอะไรในการวิ่งไปหา Library ให้เราได้

เบื้องต้นรูปแบบของชื่อไลบรารี่ด้านบนประกอบด้วย 3 ส่วนด้วยกันตามนี้

GROUP_ID:ARTIFACT_ID:VERSION

ในกรณีด้านบน GROUP_ID ก็คือ com.inthecheesefactory.thecheeselibrary ในขณะที่ ARTIFACT_ID คือ fb-like และ VERSION คือ 0.9.3

ตามความหมายแล้ว GROUP_ID เป็นการระบุกลุ่มของไลบรารี่ หากเป็น Library กลุ่มเดียวกัน(ซึ่งอาจจะมีได้หลายไลบรารี่) ก็จะตั้งเป็นชื่อเดียวกัน โดยมักจะนำหน้าด้วยชื่อแพคเกจระบุตัวตนของผู้พัฒนาแล้วค่อยตามด้วยชื่อกลุ่มของไลบรารี่ เช่น com.squareup.picasso เป็นต้น จากนั้นจึงไปตั้งชื่อไลบรารี่จริงๆใน ARTIFACT_ID เอา ส่วน VERSION ก็ไม่มีอะไรซับซ้อนมากไปกว่าเลขเวอร์ชั่นของไลบรารี่นั้นๆครับ ยกตัวอย่างเช่นไลบรารี่ของ Square ก็จะอยู่ในรูปแบบเหมือนกันจนดูออกทันทีว่าเป็นไลบรารี่ของใครนั่นเอง

dependencies {
  compile 'com.squareup:otto:1.3.7'
  compile 'com.squareup.picasso:picasso:2.5.2'
  compile 'com.squareup.okhttp:okhttp:2.4.0'
  compile 'com.squareup.retrofit:retrofit:1.9.0'
}

แล้วถามว่าเวลาเราใส่ dependency เพิ่มไปแบบด้านบนแล้วเกิดอะไรขึ้นตอนเรากด Sync Gradle? คำตอบคือมันจะส่งชื่อดังกล่าวนี้ไปถาม Maven Server ว่ามีไลบรารี่ตัวนี้เวอร์ชั่นนี้อยู่มั้ย ถ้ามี Server ก็จะระบุ Path ของไลบรารี่นี้มาให้ ซึ่งตามปกติมักจะเป็นไปตามชื่อตาม GROUP_ID/ARTIFACT_ID/VERSION_ID เลย เช่น com.squareup:otto:1.3.7 ก็จะไปตกที่ http://jcenter.bintray.com/com/squareup/otto/1.3.7 หรือ https://oss.sonatype.org/content/repositories/releases/com/squareup/otto/1.3.7/ นั่นเอง (ลองจิ้มเข้าไปดูก็จะเห็นชุดของไฟล์อยู่)

จากนั้น Android Studio จะดูดไฟล์เหล่านั้นมาฝังไว้ในเครื่องเราให้เราเอามาคอมไพล์ร่วมกับโปรเจคได้นั่นเองครับ เป็นอันเสร็จพิธี =)

น่าจะมองเห็นภาพคร่าวๆแล้วว่าจริงๆ Library ที่เราไปดึงมาใช้ก็เป็นแค่ไฟล์ไลบรารี่สกุล jar หรือ aar ที่สามารถเอามาคอมไพล์ร่วมกับโปรเจคเราได้ทันที เทียบได้กับการก็อปไฟล์เหล่านี้มาฝังไว้ในโปรเจคเลย เพียงแต่ไม่ต้องก็อปให้วุ่นวาย พิมพ์เข้าไปไม่กี่ตัวอักษรแล้วให้ Android Studio ดูดมาให้ดีกว่า สะดวกแถมยังมีระบบ Versioning อีกด้วย หล่อๆเท่ๆ

รู้จักกับไฟล์ aar

ตะกี้เราพูดไปว่ามีไฟล์อยู่สองสกุลที่สามารถเอาขึ้นไปบน Repository ให้คนอื่นเอาไปใช้ได้คือไฟล์ jar และ aar ซึ่งไฟล์ jar ก็ตรงไปตรงมาเพราะเป็นไฟล์มาตรฐานของ Java คงไม่ต้องพูดถึงมากนัก แต่อะไรคือไฟล์ aar หละ?

ไฟล์ aar นี้เป็นไฟล์เฉพาะของ Android ที่พัฒนาต่อยอดจาก jar มาอีกทีหนึ่ง เนื่องจากไลบรารี่แอนดรอยด์บางทีมีความต้องการที่จะพ่วงไฟล์ AndroidManifest.xml, Resource, Asset หรือ JNI เข้าไปด้วย ซึ่งตรงนี้จะหลุดจากมาตรฐานของ jar ไป ทางทีมพัฒนาแอนดรอยด์ก็เลยพัฒนาไฟล์ประเภท aar ขึ้นมาทดแทน เบื้องต้นก็เป็น zip file เหมือน jar ทุกประการ แต่ข้างในจะต่างกันออกไปด้วยการแพคไฟล์ jar เป็นเพียงส่วนหนึ่งของ Content ภายใน อยู่ร่วมกับไฟล์ Assets ประเภทอื่นๆดังนี้

- /AndroidManifest.xml (mandatory)
- /classes.jar (mandatory)
- /res/ (mandatory)
- /R.txt (mandatory)
- /assets/ (optional)
- /libs/*.jar (optional)
- /jni/<abi>/*.so (optional)
- /proguard.txt (optional)
- /lint.jar (optional)

ซึ่งไฟล์ jar เดิมก็จะถูกฝังอยู่ในชื่อ classes.jar นั่นเอง พ่วงมาด้วยไฟล์ประเภทอื่นที่จำเป็นต่อไลบรารี่ เพียงเท่านี้เราก็จะได้ไลบรารี่ที่สมบูรณ์แบบในการทำงานร่วมกับโปรเจคแอนดรอยด์แล้ว ดังนั้นในบทความนี้เราจะทำการสร้างไลบรารี่ในรูปแบบของไฟล์ aar กันครับ

วิธีการอัพโหลดไลบรารี่ขึ้น jcenter

เอาหละ ความรู้พื้นฐานตอนนี้น่าจะครบแล้วว่าระบบ Repository พวกนี้ทำงานยังไง จากนี้เราจะมาลองเอาไลบรารี่ที่เราเขียนเองขึ้น jcenter กันครับ ซึ่งตอนนี้น่าจะพอมองออกแล้วว่าจริงๆก็แค่เอาไฟล์ไลบรารี่ของเราขึ้นบน http://jcenter.bintray.com ได้ก็เป็นอันเสร็จละ คำถามคือจะสร้างไฟล์ aar ขึ้นมาได้ยังไงและจะเอาขึ้นไปบน Repository อย่างไร?

ไม่ยากครับไม่ยากเพราะ bintray เตรียมทุกอย่างไว้หมดแล้ว ขั้นตอนคร่าวๆจะเป็นตามรูปนี้

steps_1

แต่เนื่องจากขั้นตอนค่อนข้างมีรายละเอียดเยอะ ดังนั้นขอแบ่งเป็นส่วนๆเป็น Step by Step ตามนี้ครับ (คือจะเขียนสั้นๆก็ได้ แต่มันจะไม่เข้าใจ ดังนั้นขอเขียนยาวๆไปเลยละกันนะฮับ)

Part 1 : สร้างแพคเกจบน Bintray

Step 1: สมัครสมาชิก bintray.com ให้เรียบร้อย (Sign up แบบปกติเลย น่าจะทำเองกันได้ครับข้อนี้)

Step 2: หลังจากเป็นสมาชิกของ bintray แล้ว Login ให้เรียบร้อย แล้วกดไปที่ maven

maven

Step 3: กดที่ Add New Package เพื่อสร้าง Package ใหม่ให้ไลบรารี่ที่กำลังจะอัพโหลดขึ้น

maven2

Step 4: กรอกข้อมูลที่จำเป็นของ Package เข้าไป

maven3

ทั้งนี้ทางเราแนะนำว่าในช่อง Name ควรใส่ในรูปแบบของตัวอักษรเล็กทั้งหมดแล้วขีดคั่นระหว่างคำด้วยเครื่องหมาย - เช่นด้านบนคือ fb-like เพราะเป็น Name Convention ที่ทุกคนทำเหมือนกันหมด

เมื่อเสร็จแล้วกด Create Package เป็นอันเรียบร้อย

Step 5: จากนั้นเว็บจะพาเข้าสู่หน้า Edit Package ให้จิ้มที่ชื่อแพคเกจด้านใต้คำว่า Edit Package เพื่อไปสู่หน้าหลักของแพคเกจที่สร้างขึ้นมา

maven4

เป็นอันเรียบร้อย ตอนนี้เรามี Maven Repository ส่วนตัวบน bintray ที่พร้อมให้เราอัพโหลดไลบรารี่ขึ้นไปแล้วจ้า

maven5

Bintray เสร็จแล้ว ต่อไปถึงคิวของ Sonatype ผู้ให้บริการ Maven Central กันบ้าง

Part 2 : สร้างแอคเค้าท์ Sonatype สำหรับ Maven Central

หมายเหตุ: คุณสามารถข้ามขั้นตอน Part 2 และ 3 ไปได้ถ้าคิดว่าจะไม่อัพโหลดไลบรารี่ขึ้นบน Maven Central แต่ทางเราแนะนำให้คุณอัพโหลดขึ้นดีกว่าเพราะมีนักพัฒนาอีกจำนวนมากทีเดียวที่ยังใช้ Maven Central อยู่ครับ

Bintray นั้นเราสมัครไปเพื่ออัพไลบรารี่ขึ้น jcenter แต่ Maven Central ก็ยังทิ้งไม่ได้เพราะยังมีอีกหลายคนที่ใช้ Server นี้อยู่ ดังนั้นเราควรต้องสมัครแอคเค้าท์สำหรับเอาไลบรารี่ขึ้น Maven Central ไว้ด้วย ในที่นี้ก็คือ Sonatype นั่นเอง

การสร้างแอคเค้าท์ที่ Sonatype ก็แอบไม่ค่อย Make Sense นิดๆเพราะเป็นการสร้างแอคเค้าท์ใน JIRA Issue Tracker บน Sonatype อีกที สามารถไปสมัครที่ Sonatype Dashboard ได้เลยครับ ไม่มีอะไรซับซ้อน

หลังจากสมัครเสร็จแล้วก็ต้องสร้างขอสิทธิ์ในการอัพโหลดไลบรารี่ขึ้น Maven Central ก่อน คล้ายๆกับที่เราทำบน Bintray นั่นแหละ แต่กับ Sonatype จะดูมึนๆงงๆกว่าหน่อยนึงตรงที่เราต้องไปสร้าง Issue แทน เพื่อร้องขอสิทธิ์ในการอัพโหลดไลบรารี่ขึ้นตาม GROUP_ID ที่เราต้องการ

วิธีคือให้เข้าที่หน้า Sonatype Dashboard ... Login ให้เรียบร้อย แล้วกด Create

กรอกข้อมูลตามนี้

Project: Community Support - Open Source Project Repository Hosting

Issue Type: New Project

Summary: ใส่ชื่อไลบรารี่แบบภาพรวม (เช่น The Cheese Library)

Group Id: ใส่ชื่อ GROUP_ID ที่ใหญ่ที่สุดที่เป็นไปได้ เช่น com.inthecheeselibrary หลังจากได้รับอนุมัติแล้ว คุณสามารถใส่ GROUP_ID ทุกตัวที่ขึ้นต้นด้วย com.inthecheeselibrary ได้ เช่น com.inthecheeselibrary.somelib เป็นต้น

Project URL: URL ของไลบรารี่สักตัวนึงที่มีแผนจะเอาขึ้น เช่น https://github.com/nuuneoi/FBLikeAndroid

SCM URL: URL ของ Source Control เช่น https://github.com/nuuneoi/FBLikeAndroid.git

ที่เหลือไม่ต้องเปลี่ยนอะไร แล้วกด Create เป็นอันเรียบร้อย จากนั้นรออีกประมาณ 1 สัปดาห์(หรือนานกว่านั้น) เพื่อให้ Issue อนุมัติ หลังจากนั้นเราจะสามารถอัพไลบรารี่ขึ้น Maven Central ได้ครับ

จากนั้นให้เข้าไปที่หน้า Bintray Profile แล้วกดที่แถบ Accounts ทางด้านซ้าย ระบุ Sonatype OSS User ตาม Username ที่สร้างขึ้น

sonatypeusername

กด Update ให้เรียบร้อย เป็นอันเสร็จพิธี

Part 3 : เปิด Auto Signing ใน Bintray

อย่างที่เราบอกไว้ตั้งแต่ตอนต้นว่าเราจะอัพโหลดไลบรารี่ขึ้น Maven Central ผ่าน jcenter แต่การจะเอาไลบรารี่ขึ้น Maven Central ได้ เราจะต้อง Sign ไลบรารี่ให้เรียบร้อยก่อน ด้วยเหตุนี้เราเลยต้องตั้งค่าบน bintray เพื่อให้ระบบ Sign ไลบรารี่อัตโนมัติก่อนเอาขึ้น Maven Central

การจะทำตรงนี้ได้ เราจะต้องสร้าง Key ขึ้นมาก่อนด้วย Command Line (หากใครใช้ Windows ให้ทำผ่าน cygwin)

gpg --gen-key

ซึ่งเราจะต้องกรอกข้อมูลโน่นนี่เข้าไปพอสมควร โดยสามารถใช้ค่า Default ที่มันแนะนำมาให้ได้เลย ยกเว้นบางค่าที่เราต้องกรอกไปด้วยตัวเองเช่น Real Name และ Passphrase ก็ใส่ตามจริงไปได้เลยครับ

เมื่อสร้างเสร็จให้สั่ง

gpg --list-keys

เพื่อดูว่า Key ถูกสร้างสำเร็จหรือยัง หากสำเร็จจะขึ้นมาประมาณนี้

pub   2048R/01ABCDEF 2015-03-07
uid                  Sittiphol Phanvilai <[email protected]>
sub   2048R/98765432 2015-03-07

แล้วก็อัพโหลด Public Key ขึ้น Server กันด้วยคำสั่งด้านล่าง พร้อมแทน PUBLIC_KEY_ID ด้วยเลขฐาน 16 ที่อยู่ด้านหลัง 2048R/ ในบรรทัด pub ซึ่งในตัวอย่างนี้ก็คือ 01ABCDEF นั่นเอง

gpg --keyserver hkp://pool.sks-keyservers.net --send-keys PUBLIC_KEY_ID

จากนั้นเราจะ Export Public Key/Private Key ให้อยู่ใน Format ที่อ่านได้ด้วยคำสั่งด้านล่าง โดยแทน [email protected] ด้วยอีเมลที่ใช้ในการ Gen Key ด้านบนครับ

gpg -a --export [email protected] > public_key_sender.asc
gpg -a --export-secret-key [email protected] > private_key_sender.asc

จากนั้นเปิดไปที่หน้า Edit Profile ของ Bintray แล้วกดไปที่ GPG Signing กรอก Public Key และ Private Key ลงไปโดยใช้ข้อมูลจากไฟล์ public_key_sender.asc และ private_key_sender.asc ที่ถูกสร้างขึ้นมาตามลำดับ

gpg

เสร็จแล้วกด Update เพื่อบันทึก

สุดท้ายกดไปที่หน้าหลักของ Bintray และกดไปที่ maven

maven

กด Edit

editmaven

ติ๊กถูกที่เครื่องหมาย GPG Sign uploaed files automatically เพื่อเปิดระบบ Auto Sign

autosigned

กด Update เป็นอันเรียบร้อย เพียงเท่านี้ไลบรารี่ของเราก็จะถูก Sign ทันทีที่ถูกอัพโหลดขึ้น bintray และพร้อมจะส่งต่อไปที่ Maven Central ตามที่เราต้องการแล้ว

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

พักไว้เท่านี้ก่อนกับฝั่งเว็บ คราวนี้ถึงเวลาไปจัดการกับโปรเจคใน Android Studio ต่อ

Part 4 : เตรียมโปรเจคบน Android Studio

โปรเจคของเราอาจจะมีไลบรารี่ที่อยากจะอัพโหลดขึ้น jcenter มากกว่า 1 ตัวและอาจจะมีบางส่วนไม่ได้อยากจะเอาขึ้น jcenter ก็ได้ ดังนั้นเราจึงแนะนำให้แยก Module ออกมาอย่างชัดเจน ประกอบด้วยโมดูลของตัวอย่างการใช้งานที่รันได้และโมดูลของไลบรารี่ที่ต้องการจะอัพโหลดตามจำนวนที่ต้องการ 1 โมดูลต่อ 1 ไลบรารี่ ครับ

projectstructure

โดยวิธีสร้าง Library Module ก็ไม่มีอะไรซับซ้อนมากมาย แค่เพียง New Module แล้วเลือก Android Library เพียงเท่านี้ก็ได้โมดูลที่ใช้งานได้แล้วครับ ซึ่งตรงนี้ไม่ขออธิบายมากเพราะคนใช้ Android Studio น่าจะทำตรงนี้เป็นอยู่แล้วครับ

newmodule

ต่อไปให้ไปแก้ไขไฟล์ build.gradle ของโปรเจค (ย้ำว่าของโปรเจค ไม่ใช่ของโมดูล) แล้วแก้ไขส่วนของ dependencies ให้เป็นดังนี้

    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
    }

โดยสำคัญมากที่บรรทัดแรกต้องเป็นเวอร์ชั่น 1.1.2 เป็นต้นไป เพราะหากใช้เวอร์ชั่นต่ำกว่านั้นจะมีบั๊กกับการอัพโหลดขึ้น bintray ครับ ในที่นี้เราใช้ตัวล่าสุดไปเลยละกัน 1.2.3

ต่อไปให้แก้ไขไฟล์ local.properties เพื่อใส่รหัสผ่านและคีย์ลับสำหรับใช้ในการ Authenticate ผู้ใช้บน Bintray โดยสาเหตุที่ต้องใส่ไว้ในไฟล์ local.properties เป็นเพราะไฟล์นี้จะไม่ถูกอัพโหลดขึ้น git ด้วยนั่นเอง (ถูกใส่ไว้ในไฟล์ .gitignore โดยอัตโนมัติตั้งแต่ New Project) ข้อดีคือรับรองว่าข้อมูลไม่รั่วไหลโดยเราไม่ตั้งใจ แต่ข้อเสียคือหากเปลี่ยนเครื่องต้องมาแก้ไขไฟล์นี้เองใหม่ด้วย มิฉะนั้นจะใช้งานไม่ได้

โดยให้ใส่เพิ่มไป 3 บรรทัดดังนี้

bintray.user=YOUR_BINTRAY_USERNAME
bintray.apikey=YOUR_BINTRAY_API_KEY
bintray.gpg.password=YOUR_GPG_PASSWORD

บรรทัดแรกให้ใส่เป็น Username ของท่านในระบบ Bintray บรรทัดที่สองให้ใส่ API Key ซึ่งสามารถหาได้จากหน้า Edit Profile และกดไปที่ API Key

ในบรรทัดสุดท้าย ให้ใส่ Passphrase ที่กำหนดตอนสร้าง GPG Key ด้านบนขึ้นมา เป็นอันเรียบร้อย บันทึกและปิดไฟล์ได้ครับ

สุดท้ายให้ไปเปิดไฟล์ build.gradle ของโมดูล แล้วใส่ค่ารายละเอียดต่างๆของไลบรารี่เข้าไปในบรรทัดถัดจาก apply plugin: 'com.android.library' ดังนี้

apply plugin: 'com.android.library'

ext {
    bintrayRepo = 'maven'
    bintrayName = 'fb-like'

    publishedGroupId = 'com.inthecheesefactory.thecheeselibrary'
    libraryName = 'FBLike'
    artifact = 'fb-like'

    libraryDescription = 'A wrapper for Facebook Native Like Button (LikeView) on Android'

    siteUrl = 'https://github.com/nuuneoi/FBLikeAndroid'
    gitUrl = 'https://github.com/nuuneoi/FBLikeAndroid.git'

    libraryVersion = '0.9.3'

    developerId = 'nuuneoi'
    developerName = 'Sittiphol Phanvilai'
    developerEmail = [email protected]'

    licenseName = 'The Apache Software License, Version 2.0'
    licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
    allLicenses = ["Apache-2.0"]
}

bintrayName คือชื่อแพคเกจที่สร้างไว้บน Bintray ส่วน bintrayRepo ให้คงค่า maven ไว้เหมือนเดิมครับ ส่วนที่เหลือให้แก้ไขข้อมูลทุกตัวให้สอดคล้องกับข้อมูลจริงของไลบรารี่คุณ ซึ่งจากข้อมูลด้านบนเรากำลังจะสร้างไลบรารี่ที่เรียกใช้ด้วยโค้ดด้านล่างนี้

compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'

ปิดท้ายด้วยการดึงสคริปต์ที่ใช้ในการ Build Library และอัพโหลดไลบรารี่ขึ้น Bintray เข้ามาสองตัวด้วยการใส่บรรทัดด้านล่างนี้ไว้ที่ท้ายไฟล์ เพื่อความสะดวกในการทำงาน เราเลยขอใช้วิธีดึงสคริปต์ดังกล่าวมาจาก Github โดยตรง

apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'

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

Part 5 : อัพโหลดไลบรารี่ขึ้น Bintray ส่วนตัว

หลังจากเซตทุกอย่างเสร็จแล้ว เราสามารถอัพโหลดไลบรารี่ขึ้น Repository ส่วนตัวใน Bintray ได้ทันที ด้วยการกดไปที่ Terminal บน Android Studio

terminal

ก่อนอื่นเราจะทำการเช็คความถูกต้องของโค้ดและสร้างไฟล์ Library ขึ้นมาก่อนด้วยคำสั่ง

> gradlew install

หากทุกอย่างสมบูรณ์จะขึ้นว่า

BUILD SUCCESSFUL

จากนั้นให้พิมพ์คำสั่งด้านล่างนี้เพื่ออัพโหลดไลบรารี่ที่ Build เสร็จแล้วขึ้น Bintray

> gradlew bintrayUpload

หากไม่มีปัญหาอะไรจะขึ้นว่า

SUCCESSFUL

นั่นแหละเรียบร้อยแล้ว ! ให้ไปเช็คหน้าเว็บก็จะเห็นว่าเลขเวอร์ชั่นที่เราอัพโหลดปรากฏขึ้นมาแล้ว

firstuploaded

เมื่อกดเข้าไปดูจะเห็นไฟล์ไลบรารี่ทั้งหมดถูกเอาไปวางไว้บน Repository เรียบร้อยแล้ว! เย้

uploadedfiles

ยินดีด้วย ตอนนี้ไลบรารี่คุณออนไลน์และพร้อมให้คนอื่นใช้งานแล้วครับ

อย่างไรก็ตาม อย่าเพิ่งดีใจไป เพราะการอัพโหลดตรงนี้ ไลบรารี่เราจะยังไปไม่ถึง jcenter แต่จะไปอยู่บน Maven Repository ส่วนตัวของเราบน Bintray หากจะใช้งาน นักพัฒนาต้องกำหนด URL ของ Maven Repository ส่วนตัวของเราเสียก่อนถึงจะใช้งานได้ เช่น

repositories {
    maven {
        url 'https://dl.bintray.com/nuuneoi/maven/'
    }
}

...

dependencies {
    compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'
}

ซึ่ง url ดังกล่าวนี้สามารถดูได้จากหน้า maven บนเว็บ bintray ครับ หรือจะแทนคำว่า nuuneoi ด้วย Username ของท่านเลยก็ได้ ถ้าลองกดเข้าไปดูในลิงค์ข้างต้นก็จะเห็นว่าเป็น Maven Repository ที่บรรจุไลบรารี่ของผู้ใช้คนนั้นๆนั่นเอง

แต่ก็ตามที่ได้กล่าวไว้ข้างต้น มันไม่สะดวกต่อการใช้งานจริง นักพัฒนาท่านอื่นไม่ควรต้องมานั่งกำหนดอะไรยุ่งยากแบบนี้ ดังนั้นเราจะมาส่งไลบรารี่ของเราจาก Bintray ส่วนตัวต่อไปยัง jcenter กัน ซึ่งสามารถทำได้ด้วยการ Sync Repository ของเรากับ jcenter ต่ออีกที

Part 6 : Sync bintray ส่วนตัวเข้ากับ jcenter

วิธีการส่งไลบรารี่ต่อไปยัง jcenter นั้นทำได้ง่ายเพียงคลิกเบาๆคลิกเดียวที่ Add to JCenter

addtojcenter

แล้วก็กด Send ในหน้าต่อไป

addtojcenter2

จากนั้นรอประมาณ 2-3 ชั่วโมงเพื่อให้ทางทีม Bintray อนุมัติการร้องขอ Sync Package ตัวนี้กับ JCenter เมื่อสำเร็จก็จะได้รับเมลมาว่า "เรียบร้อยแล้วนะ" พอเข้ามาเช็คหน้า Package ก็จะขึ้นว่า Linked To JCenter แล้ว ถือเป็นอันเรียบร้อยครับ

linkedto

จากนี้นักพัฒนาท่านอื่นที่ใช้ jcenter() จะสามารถเรียกใช้ไลบรารี่ของเราได้ผ่านบรรทัดเดียวแล้ว

    compile 'com.inthecheesefactory.thecheeselibrary:fb-like:0.9.3'

วิธีการเช็คว่าไลบรารี่เราไปอยู่บน jcenter แล้วจริงๆ ให้ไล่ดูที่ http://jcenter.bintray.com/ ตามโฟลเดอร์ที่ควรเลยครับ เช่นในที่นี้ก็คือ com -> inthecheesefactory -> thecheeselibrary -> fb-like -> 0.9.3

fblikejcenter

ทั้งนี้ การ Link นี้เป็นการทำครั้งเดียว หลังจากนี้หากมีการเปลี่ยนแปลงใดๆใน Package ของเราเช่น อัพเดตเวอร์ชั่นใหม่ ลบเวอร์ชั่นเก่าทิ้ง การเปลี่ยนแปลงจะส่งผลกับบน jcenter ด้วย แต่เนื่องจากว่ามันไม่ได้เป็น Server ตัวเดียวกัน ดังนั้นอาจจะมีดีเลย์บ้าง เช่น อัพเวอร์ชั่นใหม่แล้วต้องรอสัก 2-3 นาทีถึงจะไปปรากฏบน jcenter เป็นต้น

และโปรดระวังไว้นิดนึงว่าหากเราลบ Package ทั้งอันทิ้ง ไฟล์ไลบรารี่ต่างๆบน JCenter จะไม่ถูกลบทิ้งไปด้วย ก่อนจะลบแพคเกจทิ้ง ให้เราลบไฟล์ทั้งหมดในแพคเกจทิ้งก่อน แล้วค่อยลบ Package ทิ้งครับ

Part 7 : ส่งต่อไลบรารี่ขึ้น Maven Central

การจะส่งต่อไลบรารี่จาก jcenter ขึ้น Maven Central ได้ จะต้องทำสองเงื่อนไขให้เรียบร้อยก่อน ได้แก่

1) แพคเกจนั้นเชื่อมกับ jcenter เรียบร้อยแล้ว

2) เปิด Repository บน Maven Central สำเร็จแล้ว

วิธีการเอาขึ้น Maven Central นั้นง่ายมากกกกกกกก แค่กดไปที่ Maven Central ในหน้ารายละเอียดแพคเกจ

syncmavencentral

แล้วก็กรอก Username/Password ของ Sonatype ลงไป กด Sync ซะะะ

syncmavencentral2

เมื่อสำเร็จ ตรง Sync Status จะขึ้นว่า Successfully synced and closed repo ก็เป็นอันเรียบร้อย ไลบรารี่ไปอยู่บน Maven Central เรียบร้อยแล้วจ้า แต่ถ้าไม่สำเร็จมันก็จะขึ้น Error ตรงช่อง Lasy Sync Errors ก็ต้องแก้ไขกันไปเป็นจุดๆ เพราะการอัพไลบรารี่ขึ้น Maven Central นั้นค่อนข้าง Strict มาก เช่น Dependency ห้ามใช้เครื่องหมาย + เป็นต้น ก็แก้ไขกันไปตาม Error ที่ระบุมาครับ

เพื่อเช็คให้เรียบร้อยว่าไลบรารี่ขึ้นไปบน Maven Central แล้วจริงๆ ให้เข้าไปดูที่ Maven Central Repository แล้วกดหาไฟล์ตาม Folder เลย เช่นในที่นี้ก็ com -> inthecheesefactory -> thecheeselibrary -> fb-like -> 0.9.3 หากเจอก็ถือว่าเรียบร้อยคร้าบผม =)

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

จบเพียงเท่านี้ครับ รอดูไลบรารี่เด็ดๆจากเพื่อนๆอยู่น้า =)

ผู้เขียน: nuuneoi (Android GDE, CTO & CEO at The Cheese Factory)
นักพัฒนาแบบ Full-Stack ที่มีประสบการณ์ในการพัฒนาแอพฯแอนดรอยด์มากว่า 6 ปีและอยู่ในวงการพัฒนาแอพฯมือถือมากว่า 12 ปี มีความสนใจทางด้าน Infrastucture, Service Side, Design, UI&UX, Hardware, Optimization, Cooking, Photographing, Blogging, Training, Public Speaking และรักที่จะแชร์เรื่องราวให้ผู้คนได้อ่านได้ฟังกันผ่าน Blog