android-projesi-nasil-git-submodule-kutuphanesi-yapilabilir

Image designed by Author on Canva

Bu yazıda “Bir Git Submodule kütüphanesi nasıl yapılabilir?” sorusuna cevap vereceğim ancak nereden başlayacağımı tam olarak bilmiyorum. En iyi başlangıç sanırım “Bir Android projesi başka bir Android projesine nasıl eklenir?” sorusunu kendime ilk sorduğum zamana geri dönmek olacak. Böyle bir ihtiyaç neden ve ne zaman doğdu?

Her şey, 2019 bahar aylarında başlamıştı. Peakup’ta işe girme sürecim devam ederken teknik görüşme esnasında Peakup Labs departman yöneticisi Emrah Uslu’yu “Kaç proje yapacağız?”, “Nasıl projeler yapmayı düşünüyorsunuz?”, “Takımda Native Mobil geliştirici var mı? (Bu soru Legacy kod var mı anlamına gelir ve sorulması gerekir)” … vb. birçok soruyla güzel darlamıştım, o da bana “Yapılacak çok proje var, hiç merak etme,” diye karşılık verdi ve sözlerine, seneler sürecek tek bir büyük proje yerine irili ufaklı birçok proje yapacağımızı ekledi.

Bir önceki iş yerimde aklıma düşmüş “farklı projeler arasında ortak olarak kullanılabilecek bir kütüphane” fikri bir kez daha mantıklı geldi. Emrah Bey’e görüşme esnasında bundan bahsettim mi hatırlamıyorum, işbaşı yaptığım ilk günden itibaren, bu tarz bir ortak kütüphane yapmamı özellikle talep etmişti.

Photo by  Will van Wingerden  on  Unsplash

Photo by Will van Wingerden on Unsplash

Örneğin “Login sayfası” her projemizde var ve hepsinde aynı, şirket Microsoft partner olduğu için Microsoft’un login sayfasını da WebView olarak ekleyeceğiz. Dil, tema ayarları gibi ortak sayfaların yanında; onlarca method, özelleştirilmiş style ve theme, ortak tasarım dilini oluşturacak olan envai çeşit custom view, extension function, web servis request mimarisi, DSL… yazacağız. Bunların her projede bulunması gerekiyor, üstüne üstlük hepsi aynı. Kopyala-yapıştır döngüsüne girip projeleri çöpe çevirmektense bu ortak sayfaları ve özellikleri ayrı bir kütüphaneye ekleyip oradan ortak bir şekilde kullanmak daha basit ve akla yatkın değil midir?

Kopyala-yapıştırın çok büyük bir zararını daha önce şöyle yaşamıştım: Birbirinden forklanarak oluşturulmuş 8–10 tane proje vardı. En ufak servis değişikliği, bugfix, refactor… bu projelerin hepsinde aynı değişikliği amele gibi tekrar tekrar yapmak anlamına geliyordu. Ne derseniz deyin bu iyi bir geliştiricilik örneği değildir. Yapmayın. Uzak durun. Fork özelliğini çok daha verimli kullanabilirsiniz, kullanın.

Image designed by Author on   Creately

Image designed by Author on Creately

Şöyle bir düşündüğünüz zaman göreceksiniz ki Open/Closed Principle, Software Reuse Don’t Repeat Yourself, hatta SOLID prensiplerinin hepsi kütüphane sistemlerini destekler; kod kopyala-yapıştır yapmayı da sağlıklı bulmaz.

Teknik Olarak?

“Git Submodule Projesi”nin ne olduğunu ve neden gerekli olduğunu yeterince anlattığımı düşünüyorum. Zihninizde “Peki, anladık da bunu teknik olarak nasıl yapacaksın?” gibi bir soru oluştuysa buyurun: Kütüphane deyince aklıma başta direk JAR dosyaları geldi ancak gördüm ki JAR dosyaları sadece Java SDK’sındaki sınıfları barındırabilir; Android SDK’sındaki Activity, Fragment, SharedPreferences, WifiManager… gibi sınıfları barındıramaz. Benim ihtiyacım olan kütüphane yapısında Activity SharedPreferences gibi sınıflar bulunmak zorunda. Bu durumda aklımıza gelen bir diğer kütüphane çeşidi ise AAR dosyaları.

AAR dosyalarının birkaç dezavantajı var: Bunlardan bir tanesi ve en büyüğü, herhangi bir kod ekleyişinizde yeni bir AAR uzantılı dosya yaratıp bunu asıl projenize eklemeniz gerektiğidir. Peakup’ta legacy kodun bulunmadığı, kütüphanenin de asıl uygulamaların da tamamen sıfırdan, birlikte ve paralel yazılacağı düşünüldüğünde; AAR dosyaları ile uğraşmak gerçekten eziyet verici. Kütüphane önceden yazılmış ve hazırlanmış olsa tamam, daha küçük yer kaplayacağı için tabii ki AAR’ı tercih ederdim.

Photo by  Patrick Lindenberg  on  Unsplash

Photo by Patrick Lindenberg on Unsplash

İhtiyacımızı karşılayacak kütüphanenin özelliklerini şöyle sıralayabiliriz:

  • Dinamiklik,

  • Sürekli değişime yatkınlık, (Bu değişim sürecinde geliştiriciye çok iş çıkarmaması önemli.)

  • Birçok proje yapılacağı ve bu yeni yapılacak projelerde kütüphaneye kod ekleneceği zaman var olan projelerin de bozulmaması için;

Open / Closed Principle’a tapınma derecesinde uyumluluk ve VSTS’ten indirildiğinde çalışabilirlik.

İhtiyaçları belirledikten sonra seçenek netleşti. Git’in bir özelliği olan Submodule.

Kütüphane, ilk olarak her projede aynı şekilde kullanılacak bir Authenticator katmanı içermeliydi. Malum giriş yapma ekranı. Kütüphanenin en büyük işi bu olduğu için adını PeakAuth olarak belirledim; o günden sonra PeakAuth gel, PeakAuth git… Resmen çocuğum gibi oldu. Sevdim, iOS’a geçene kadar sürekli geliştirdim, sürekli bir şeyler ekledim. Peakup’ta yazdığım ilk Android uygulama EnviSense’ti, sürekli “Aaa! Bu extension function’ı ben başka projelerde de kullanırım, PeakAuth’a ekleyeyim. Aaa! Ben bu tarih formatlarını her projede neden tekrar yazayım ki? Hemen PeakAuth’a ekleyeyim…” diye diye, kütüphanede ortak kullanılacak özelliklerle kod parçacıkları zamanla, üzerine eklene eklene büyüdü. Çocuk örneği verdim ya, tam bir çocuktu yani.

Photo by   Suzanne D. Williams   on   Unsplash

Photo by Suzanne D. Williams on Unsplash

Not: Android Git Submodule, Git’in bir özelliği olduğu için kütüphanede asıl projemiz de Git içerisinde barınmak zorunda. Git’in önemine ve kullanma sebebimize girmiyorum bile. Ayrıca ekran görüntülerinde proje id kısımlarına takılmayın, eski şirketimin projesine erişimim olmadığı için yeni bir projede tekrar yapmak zorunda kaldım.



Bir Uygulamayı Nasıl Android Git Submodule Hâline Getirebiliriz?

Android Studio’da ileride kütüphane olacak olan projemizi açtık, ortak kodlarımızı yazdık; artık sıra bunu kütüphaneye çevirmeye geldi.

Bunun için yapmamız gereken 3 basit adım var:

  • Android’de bir kütüphane projesi, başlatıcı (Launcher) bir activity’e sahip olamaz. AndroidManifest dosyasındaki hiçbir activity, Launcher etiketine sahip olamaz. Yorum satırına dönüştürebilirsiniz:

code
<activity android:name=".MainActivity" android:exported="true">
<!-- <intent-filter>
         <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
     </intent-filter>-->
</activity>
  • Android’de bir kütüphane projesi, app level gradle.build dosyasında en yukarıda com.android.application etiketine değil com.android.library etiketine sahip olur.


Screenshot taken by Author

Screenshot taken by Author

  • 2. madde ile aynı dosyada, default config bölümü altında normalde uygulamalarda bulunan applicationId kütüphanelerde bulunmaz, silinmesi gerekir.

Screenshot taken by Author

Screenshot taken by Author

Sync yapın, commit & push yapın işte bu kadar. Artık PeakAuth diğer projelerde de ortak olarak kullanılabilecek bir kütüphane haline geldi.



Bir Git Submodule Kütüphanesini Başka Bir Android Projesine Nasıl Ekleyeceğiz?

Kütüphane projemizi oluşturduktan sonra sıra bunu nasıl kullanıp Android projelerine ekleyeceğimize geldi. İsterseniz bunu Git’teki README dosyasına yazın ki ekip hâlinde çalışıyorsanız diğer arkadaşlarınıza kolaylık olsun. Hem bu tip önemli noktaların şirketteki tek bir geliştiriciye bağlı olmaması gerekir. Ayrıca bunu sadece yapanın değil; diğer geliştiricilerin de çok basit bir şekilde anlayabilmesi, ekleyebilmesi ve ihtiyaç olduğunda kullanabilmesi gerekir.

Çok önemli bir noktayı en başta belirtmem gerektiğini düşünüyorum: Aşağıda yazdığım son adıma kadar sync işlemi yapılmaması gerekmektedir. Tüm bağlantı ve ayarlar tamamlandıktan sonra sync yapılacaktır.

  • Kütüphaneyi eklemek istediğiniz proje, terminalden cd komutu çalıştırılarak açılır. İçerisine aşağıda gösterilen kod yazılır, ardından kütüphanenin linki eklenir: git submodule add https:…

Veya daha basit bir şekilde SourceTree üzerinden de ekleyebilirsiniz. Projenize Git Submodule ekleyecekseniz -hele de benimki gibi dinamik bir amacı varsa- bence SourceTree kullanın. Proje içerisindeki Submodule’ün yönetimi daha basit olacaktır. Projeyi SourceTree’de açtığınızda, alttaki ekran görüntüsünde de gördüğünüz gibi soldaki boş alanda sağ tıklayıp Add Submodule seçin.

Screenshot taken by Author

Screenshot taken by Author

Açılan pencerede gerekli bilgileri ve Submodule’ün linkini girin. Eğer Submodule’de birden fazla branch varsa Advanced Options seçeneği ile hangi branche’ı bağlamak istediğinizi yazabilirsiniz. Ardından tabii OK butonuna basmanız gerekiyor. Burada eklediğiniz dosyaya verdiğiniz isim çok önemlidir. Biz Peakup Labs mobil geliştiricileri olarak PeakAuth kütüphanesinin bulunacağı dosyaya haliyle “peakauth” ismini veriyoruz.


Screenshot taken by Author

Screenshot taken by Author

Bu adımın ardından veya git submodule add komutunu çalıştırdığınızda asıl projenize .gitmodule dosyası otomatik olarak eklenecektir.

  • Projenin settings.gradle dosyasına girilerek şu satırlar eklenir:

    code
    :include ':peakauth'
    project(':peakauth').projectDir = new File('peakauth/app')
  • Projenin application level build.gradle dosyasına şu satır dependency olarak eklenir:

code
implementation project(":peakauth")
  • Sync yapılır. Yukarıda da söylediğim gibi, bu adıma kadar sync yapılmaması gerekmektedir.

Eğer herhangi bir ara adımda yanlışlıkla sync yaptıysanız tüm değişiklikleri Git üzerinden Reset/Discard yapıp, eklenen dosyaların tümünü silip sürece baştan başlamanız gerekmektedir. Son commit’e dönün yani. (“Git reset HEAD” de çalıştırabilirsiniz.) Ben birkaç kere yaptım ve baştan başlamaktan daha temiz bir yol bulamadım. Ayrıca kütüphane ekleme sürecine başlamadan önce de bir commit atmanızı tavsiye ederim. Başka değişiklikler olmasın ki toplu reset yaptığınızda kod kaybına uğramayın.

Screenshot taken by Author

Screenshot taken by Author

Projeniz yukarıdaki ekran görüntüsündeki gibi iç içe görünüyorsa Android Submodule kütüphanesi kullanıma hazır demektir. Gördüğünüz üzere, içinde istediğiniz gibi gezebilirsiniz ki bu da AAR tipi kütüphanelerde olmayan bir özellik. Baştaki icon da peakauth’un bir kütüphane olduğunu gösterdiği için önemli. Alttaki ekran görüntüsünde de SourceTree üzerinde projenizin nasıl görünmesi gerektiğini görebilirsiniz.

Screenshot taken by Author

Screenshot taken by Author

Alttaki peakauth yazısına çift tıkladığınızda herhangi bir şey olmayabilir çünkü projedeki peakauth submodule dosyası şu an boştur. Terminalde cd komutu ile submodule’ün dosyasını açmanız ve orada git clone ile yine submodule projesini çekmeniz gerekebilir. Bu işlemin ardından, tıkladığınızda yeni bir sekmede submodule projemiz açılacaktır.

Screenshot taken by Author

Screenshot taken by Author


Hayat Kurtarıcı Not: Submodule’ü sadece kendi Repository’sinden, kendi içinden güncelleyin. EnviSense’in içindeki PeakAuth’u güncellersek bu, asıl PeakAuth’a da yansıyıp kütüphaneyi kullanan diğer projelerimizi bozabilir. Submodule’ü dikkatli kullanmazsanız ortalığı fena karıştırabilirsiniz. Her ne kadar tatlış da olsa yönetimi, projeler ilerledikçe zorlaşabilir.

Android’de Submodule kütüphane kullanımı hakkında daha fazla bilgi istiyorsanız alttaki 2 kaynak benim için çok faydalı olmuştu. Onları da buraya ekliyorum:

Bu yazı aslında daha önce çalıştığım bir şirket olan Peakup Blog’da yayınlanmıştır. Orada ekran görüntüleri bozulduğu ve yazının sahibinin ben olduğum belli olmadığı için buraya aktarmayı tercih ettim.

İyilik ve sevgi dolu, bol okumalı günler dilerim.