Keeping in touch with the domain experts is crucial in DDD in order to gain domain insight and as Scott Millett and Nick Tune says in their book called Patterns, Principles, and Practises of Domain Driven Design, DDD refers domain experts as people who deeply understand the business domain from its policies and work flows, to its nuisances and idiosyncrasies. They can be anyone who has a great grasp and understanding for the domain you are working in regardless of title. And also its recommended that to enable a high level of collaboration, you (being a developer) collocate the development team with domain experts who will be on hand to answer questions and participate during analysis at impromptu corridor or break room meetings.
Below there will find some questions which you can ask to domain experts that can make you understand easier the ultimate goal. The questions were taken from the blog page of Greg Young
-Where does the need of this system come from?
-How will this system give value to the business?
-What would happen if this system wasn't built?
-What is the smallest possible thing we can do to deliver this business value?
-What is the need this system fills, not “what it does”
-If I turned off the server tomorrow who would be the first person to notice and why?
-How would you verify that this is working correctly?
-What is the earliest point you can know whether the system has any value to you? How will we do this?
-Why are we starting here?
-What is the minimal setup needed for first release?
-If we could keep only half of the existing features, what would they be?
-How much money do we gain or save from this change?
-What is the smallest step that would give us the most benefit?
-What is the least beneficial technology in our stack?
-How expensive would it be NOT to solve this problem?
-What if we take 1 developer away from this project?
-What would happen if our entire datacenter crashed and all data is lost?
-What is the time frame?
-When this must be in sandbox/ready for testing/production?
-Lay out few different directions to implement this (in terms of SW architecture)?
-How they differ?
-How much will cost us to switch from variant A to B?
-Who will be engaged in this task/project?
-Who will give feedback/requirements?
-Who will tell that it is completed.
-Under what exact circumstances / business operations could this issue occur?
-What are the chances of this happening? Or, how big is the window of opportunity for this to occur?
-What is the business impact of something like this happening?
-Is it possible to mitigate the chances of it happening through design of the business operations?
-Can it be automatically detected?
-How quickly can it be detected after the issue occurs?
-Can it be compensated (fixed) after occurring?
-Can the compensation be automated and transparent?
-What part of the business solution is not solved (or is the domain expert unsure in any area)?
-What in your processes changes most? Why?
-What part of the system took you the longest to learn/understand? Why?
-How’s this any different from … ?
-Are we really in the business of … ?
-Is it going to be worth anything beyond the first use ?
-How hard would it be for a competitor to come up with the same thing ?
-How likely are users to understand this feature ?
-Do you know what end users want, what they care about? Can we give it to them?
-How much can be removed from the product? Does it get better or worse?
-Do you know where bottlenecks occur in the system?
mustafa güven. developer.
mostly about "advanced android, ios, game and augmented reality" development
19 Ekim 2017 Perşembe
8 Kasım 2013 Cuma
Android Kitkat'la gelen en önemli yenilik: ART!
Merhaba,
Android 4.4 Kitkat'ın akıllı cihazlarda kullanılabilir hale gelmesine yakın bir süre kala herkesin gözü yeni özelliklerin neler olduğuna kilitlenmiş durumda. Yazıcı desteği, daha kullanışlı ve etkili yeni efektli geçişler (transitions), tam ekran kapsama modu (full screen immersive mode), hafıza kullanımını analiz eden araçlar, vs... Tamamını buradaki videodan öğrenebilirsiniz. Geneli kitkat'ın kimliğini açıklar nitelikte ancak burada bahsedilmeyen bir özellik daha var: ART!
ART nedir? Neden daha etkili? Nasıl çalışıyor?
2 yıllık gizli bir çalışmanın sonucunda Kitkat ile android kullanıcılarının hizmetine sunulacak olan ART, ilk izlenimlere göre -her ne kadar birlikte çalışma imkanları olsa da- dalvik'in koltuğuna göz dikiyor gibi. Daha hızlı ve verimli çalışacak uygulamalar ile daha uzun pil ömrü de ilk vaatlerinin arasında. Peki neye dayanarak? Belirtildiğine göre ART'ta çalışma zamanında uygulamanın yürütülme süreci (execution handling) Dalvik'teki mekanizmadan tamamen farklı. Bilindiği üzere Dalvik'teki mantık bir JIT compiler desteği ile bytecode'un bir dalvikbytecode'a (dex) çevrilmesi şeklinde ilerliyordu. Geliştirici önce uygulamanın bir kısmını derler (compile eder) ortaya bir apk formatında veri çıkar daha sonra uygulama her çalışacağı sırada mutlaka cihaz tarafından tekrar bir yorumlama sürecinden daha geçirilirdi (ya da geçirilir diyelim şu an ki sistem bu şekilde işliyor çünkü). Bu tekrar tekrar yorumlama hadisesi, hem sürece ek bir yük getirmekte hem de kısmen verimsiz sayılabilmekteyken uygulamanın çeşitli donanım ve mimarilerde daha kolay çalışabilmesini sağlama avantajı bu olumsuz etkileri gözardı etmemize neden oluyordu. ART işte bu noktada, bu süreci uygulama ilk yüklendiğinde bytecode'un direk makine diline compile edilmesini sağlayarak tamamen farklı bir temel üzerinden hareket etmekte ve sonucunda uygulamaları tamamen native hale getiren bir hizmet sunmakta. Bu sürece Ahead-Of-Time Compilation (AOT) adı veriliyor. AOT ile sanal makinenin veya kodun yorumlanması süreci ortadan kaldırılarak açılış ve çalışma süresi çok yüksek oranda artmış oluyor.
Android 4.4 Kitkat'ın akıllı cihazlarda kullanılabilir hale gelmesine yakın bir süre kala herkesin gözü yeni özelliklerin neler olduğuna kilitlenmiş durumda. Yazıcı desteği, daha kullanışlı ve etkili yeni efektli geçişler (transitions), tam ekran kapsama modu (full screen immersive mode), hafıza kullanımını analiz eden araçlar, vs... Tamamını buradaki videodan öğrenebilirsiniz. Geneli kitkat'ın kimliğini açıklar nitelikte ancak burada bahsedilmeyen bir özellik daha var: ART!
ART nedir? Neden daha etkili? Nasıl çalışıyor?
2 yıllık gizli bir çalışmanın sonucunda Kitkat ile android kullanıcılarının hizmetine sunulacak olan ART, ilk izlenimlere göre -her ne kadar birlikte çalışma imkanları olsa da- dalvik'in koltuğuna göz dikiyor gibi. Daha hızlı ve verimli çalışacak uygulamalar ile daha uzun pil ömrü de ilk vaatlerinin arasında. Peki neye dayanarak? Belirtildiğine göre ART'ta çalışma zamanında uygulamanın yürütülme süreci (execution handling) Dalvik'teki mekanizmadan tamamen farklı. Bilindiği üzere Dalvik'teki mantık bir JIT compiler desteği ile bytecode'un bir dalvikbytecode'a (dex) çevrilmesi şeklinde ilerliyordu. Geliştirici önce uygulamanın bir kısmını derler (compile eder) ortaya bir apk formatında veri çıkar daha sonra uygulama her çalışacağı sırada mutlaka cihaz tarafından tekrar bir yorumlama sürecinden daha geçirilirdi (ya da geçirilir diyelim şu an ki sistem bu şekilde işliyor çünkü). Bu tekrar tekrar yorumlama hadisesi, hem sürece ek bir yük getirmekte hem de kısmen verimsiz sayılabilmekteyken uygulamanın çeşitli donanım ve mimarilerde daha kolay çalışabilmesini sağlama avantajı bu olumsuz etkileri gözardı etmemize neden oluyordu. ART işte bu noktada, bu süreci uygulama ilk yüklendiğinde bytecode'un direk makine diline compile edilmesini sağlayarak tamamen farklı bir temel üzerinden hareket etmekte ve sonucunda uygulamaları tamamen native hale getiren bir hizmet sunmakta. Bu sürece Ahead-Of-Time Compilation (AOT) adı veriliyor. AOT ile sanal makinenin veya kodun yorumlanması süreci ortadan kaldırılarak açılış ve çalışma süresi çok yüksek oranda artmış oluyor.
Ne kadar daha iyi?
Şu an için Kitkat ile gelecek ilk ART versiyonunda ne gibi verimli kazanımlar olacak ölçümlemek kolay değil dolayısıyla kullanımı yaygınlaşmadan temsili rakamlar söylemek de pek mümkün değil ancak yine şimdiye kadar yapılan testlerde bir çok uygulama için yürütme (execution) sürecinin 2 kat hızlandığı yönünde iddialar mevcut. Bu da demek oluyor ki hem uzunca çalışan ve işlemciyi yoğun düzeyde kullanan işlemler (task) daha hızlı tamamlanacak hem de normal uygulamalardaki dokunma, diğer sensörlere dayalı işlemler veya animasyon gibi olaylar daha hızlı ve göze hoş hale gelmiş olup işlemcinin daha az çalışması sonucu pil ömrü de uzamış olacak.
Dezavantajları neler?
Elbette AOT'un da bazı dezavantajları var fakat getirdiği faydalar yanında bunlar gayet önemsiz kalır nitelikte. Bunlardan ilki her ne kadar çok önemli boyutlarda olmasa dahi (tahminen uygulama başına %10-%20 arası) depolama biriminin daha kolay dolacağı çünkü tümüyle makine koduna çevrilerek derlenmiş kod bytecode'dan daha fazla yer kaplamış olacak. (Bunun nedeni bytecode içindeki her sembolün makine kodunda birden çok komutu temsil edebiliyor olması). Kafalarda APK'ların boyutlarının belirttiğimiz oranda artacağı düşüncesi doğabilir bu noktada şunu hatırlatmakta fayda var depolama birimindeki artıştan bahsederken uygulamanın sadece kod tarafında olacak bir artıştan bahsediyoruz. Örnekle Google+'ın son apk'sının boyutu 28.3MB fakat bunun yalnızca kod kısmı 6.9MB. Bir diğer dezavantaj ise yükleme süresi sorunsalı. Ne kadar uzayacak? Aslına bakılırsa bu da yine uygulamanın boyutuna göre değişecek. Ufak çaplı uygulamalar yüksek ihtimal hiç etkilenmeyecek ancak facebook veya google+ gibi daha yüksek ve karmaşık yapıdaki uygulamalar sizi biraz bekletecek gibi gözüküyor. Ayrıca ART'ı kullanmak için yapacağınız ilk geçişte cihazınızdaki uygulama sayısının çokluğu sizi birazcık sabır imtihanına maruz bırakabilir.
Sonuç
ART her ne kadar heyecan verici ve android team için tünelin ucundaki ışık gibi görünse de henüz ses getirecek lansmanının yapılmamasının bazı nedenleri var. Google hala bu oluşuma deneysel bir yenilik gözüyle bakıyor ve daha da önemlisi sistemin stabil çalışıp çalışmaması konusunda kesinlik yok. ART'ı denemek için Ayarlar > Geliştirici Seçenekleri > Çalışma zamanı ekranına gidip ART'ı işaretleyebilirsiniz. (Bilginiz olsun, bu süreç tüm yüklü uygulamalarınızı ART'a hazırlamak için 10 dakikaya yakın bir süre gerektirebilir.)
12 Ekim 2013 Cumartesi
26 Mart 2013 Salı
8 Nisan 2012 Pazar
Farklı projelerde JAR library'de tanımlanmış android resource dosyalarını kullanmak
Merhaba, uzun bir aradan sonra yeni bir makaleyle tekrar beraberiz. Başlık biraz garip oldu ama anlatmak istediğim şeyi daha farklı nasıl yazarım bilemedim. Problemimiz şu: Farklı projelerde kullanmak amacıyla kendi library'inizi (jar dosyanızı) oluşturduğunuzu varsayalım. Eğer paket içinde herhangi bir android resource dosyası mevcutsa maalesef bu kütüphaneyi import ettiğinizde hata ile karşılaşacaksınız. Bunun nedeni resource dosyalarının final static olarak tanımlanması ve her projenin "R"esource'unun diğerlerinden farklı olmasından kaynaklanmaktadır. Hemen basit bir örnek.
Diyelim ki kütüphanenizde showToast adinda kendinize özel geliştirdiğiniz bir method var. Bu method adından da anlaşılacağı üzere kullanıcıya mesaj vermek için oluşturduğunuz bir method. Gösterilen mesajda öyleya sadece strings.xml resource'unda tanımlı MESAJ_DESC adındaki parametreye ne tanımlanmışsa onu gösteriyor diyelim. Doğal olarak istediğiniz şey, bu kütüphaneyi kullandığınız her projede strings.xml'deki MESAJ_DESC parametresini özelleştirebilmek olacak. Ancak MESAJ_DESC parametresinin ID'sinde bulunan değer, kütüphanenin oluşturulduğu projenin Resource dosyasında neyse her zaman o olacağından uygulama MESAJ_DESC parametresini bulamayacak, hata verecek ve bu library'i kullanamayacaksınız. İşte bu gibi durumlarda aşağıdaki method ile bu problemin önüne geçmeniz mümkün.
Diyelim ki kütüphanenizde showToast adinda kendinize özel geliştirdiğiniz bir method var. Bu method adından da anlaşılacağı üzere kullanıcıya mesaj vermek için oluşturduğunuz bir method. Gösterilen mesajda öyleya sadece strings.xml resource'unda tanımlı MESAJ_DESC adındaki parametreye ne tanımlanmışsa onu gösteriyor diyelim. Doğal olarak istediğiniz şey, bu kütüphaneyi kullandığınız her projede strings.xml'deki MESAJ_DESC parametresini özelleştirebilmek olacak. Ancak MESAJ_DESC parametresinin ID'sinde bulunan değer, kütüphanenin oluşturulduğu projenin Resource dosyasında neyse her zaman o olacağından uygulama MESAJ_DESC parametresini bulamayacak, hata verecek ve bu library'i kullanamayacaksınız. İşte bu gibi durumlarda aşağıdaki method ile bu problemin önüne geçmeniz mümkün.
public static int getResourceIdByName(String packageName, String className, String name) { Class r = null; int id = 0; try { r = Class.forName(packageName + ".R"); Class[] classes = r.getClasses(); Class desireClass = null; for (int i = 0; i < classes.length; i++) { if(classes[i].getName().split("\\$")[1].equals(className)) { desireClass = classes[i]; break; } } if(desireClass != null) id = desireClass.getField(name).getInt(desireClass); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } return id; }Kullanımı için
int id = getResourceIdByName(context.getPackageName(), "string", "showToast");(Kaynak: http://stackoverflow.com/questions/1995004/packaging-android-resource-files-within-a-distributable-jar-file)
4 Şubat 2012 Cumartesi
Android ile Reflection (Android and Reflection)
Merhaba, (Hello)
Android ile ilgili yazılarımıza "reflection - yansıma" konusuyla devam ediyoruz. Aslında bu konuyu android için özelleştirmek çok mantıklı olmasa da android ile ilgili yazılan türkçe makaleler arasında örnek teşkil etmesi bakımından değinmek faydalı olacaktır diye düşünüyorum. Keza reflection zaten gerek java gerekse de .net geliştiricilerinin zaman zaman projelerinde kullandıkları önemli bir kütüphane. Dilerseniz konuyu biraz daha genel boyuta taşıyarak -bilakis daha önceden hiç kullanma fırsatı olmayan arkadaşlar için- kısa bir şekilde reflection'ın ne olduğu ve ne işe yaradığından bahsederek başlayalım. Reflection çok basit anlamda, herhangi bir nesnenin üye elemanlarına çalışma zamanında (runtime) ulaşıp, bu elemanların çağrılmalarına (invoking) imkan veren yapıdır. Reflection'ın avantaj ve dezavantajlarına girmek istemiyorum, internette bir çok kaynaktan bunları zaten detaylıca öğrenmek mümkün yalnız konumuz dışında olsa da belirtmekte fayda gördüğüm iki madde olacak. Bunlardan ilki reflection konusunda C# ile Java arasında bilinmesi gereken belki de en temel farklılık ile ilgili.
(We are continuing to talk about android with the "Reflection". Basically there are a lot of C# or Java developers who work with it on their projects time to time so it's a keypoint for both side not just Android. In a very simple manner the reflection is the ability to discover the members of a class and to invoke methods at runtime. I don't want to talk about advantages or disadvantages of the reflection because there are a few sources that may help you to lead what is it about on the internet but for a general knowledge I would like to mention two important things about differences between c# and java reflection)
Android CodeBehind'da bir TextView nesnesi yaratırken yaptığımız işlem (Creating a TextView from codebehind on Andriod)
Çalışma zamanında reflection ile yukarıdaki olayın gerçekleştirilmesi: Runtime'da bir TextView nesnesi yaratırken yaptığımız işlem -Constructor'a ulaşmak- (Creating a TextView from codebehind at runtime with using reflection)
Bu aşama ve sonrasında yapılacaklar istenen şeye göre elbette değişkenlik arzedecektir, biz burada örnek olması açısından retobj isimli nesnemizi View'a cast ederek ilgili layout'a ekleyeceğiz. (The rest is up to you, I casted retobj to View and added it to a linearLayout as following to set an example)
Android ile ilgili yazılarımıza "reflection - yansıma" konusuyla devam ediyoruz. Aslında bu konuyu android için özelleştirmek çok mantıklı olmasa da android ile ilgili yazılan türkçe makaleler arasında örnek teşkil etmesi bakımından değinmek faydalı olacaktır diye düşünüyorum. Keza reflection zaten gerek java gerekse de .net geliştiricilerinin zaman zaman projelerinde kullandıkları önemli bir kütüphane. Dilerseniz konuyu biraz daha genel boyuta taşıyarak -bilakis daha önceden hiç kullanma fırsatı olmayan arkadaşlar için- kısa bir şekilde reflection'ın ne olduğu ve ne işe yaradığından bahsederek başlayalım. Reflection çok basit anlamda, herhangi bir nesnenin üye elemanlarına çalışma zamanında (runtime) ulaşıp, bu elemanların çağrılmalarına (invoking) imkan veren yapıdır. Reflection'ın avantaj ve dezavantajlarına girmek istemiyorum, internette bir çok kaynaktan bunları zaten detaylıca öğrenmek mümkün yalnız konumuz dışında olsa da belirtmekte fayda gördüğüm iki madde olacak. Bunlardan ilki reflection konusunda C# ile Java arasında bilinmesi gereken belki de en temel farklılık ile ilgili.
(We are continuing to talk about android with the "Reflection". Basically there are a lot of C# or Java developers who work with it on their projects time to time so it's a keypoint for both side not just Android. In a very simple manner the reflection is the ability to discover the members of a class and to invoke methods at runtime. I don't want to talk about advantages or disadvantages of the reflection because there are a few sources that may help you to lead what is it about on the internet but for a general knowledge I would like to mention two important things about differences between c# and java reflection)
- C#'ta reflection assembly seviyesinde olmaktayken, Java'da class seviyesinde uygulanmaktadır. .NET'te assemblyler dll'lerde tutulduğundan dolayı assembly load edilerek yapılırken java da class'ın kendisine erişim sağlanarak gerçekleştirilir. (Reflection in C# is done at the assembly level while reflection in Java is done at the class level. Since assemblies are typically stored in DLLs, one needs the DLL containing the targeted class to be available in C# while in Java one needs to be able to load the class file for the targeted class.)
- .NET'te ilgili nesnenin metadatası System.Type nesnesinde enkapsüle edilirken Java'da java.lang.Class nesnesi içerisinde enkapsüle edilir. (To retrieve the metadata class from an instance of the target class, the getClass() method is used in Java while the GetType() method is used in C#)
Type x = typeOf(y); // C# Class x = y.class; //Javaİkinci madde de belirtmiş olduğum nedenden dolayı biz de android'de reflection ile uğraşırken metadatasına ulaşmak istediğimiz bütün nesnelerin enkapsüle edilmesi işlemi esnasında Class nesnesini kullanıyor olacağız. (We are going to use Class object while encapsulating objects on Android because of the reason described section two)
Class x = Object.class; Constructor[] constructors = x.getDeclaredConstructors(); Field[] fields = x.getDeclaredFields(); Method[] methods = x.getDeclaredMethods(); for (Constructor constructor : constructors) { //constructorlar } for (Field field : fields) { //fieldlar } for (Method method : methods) { //methodlar }
Android CodeBehind'da bir TextView nesnesi yaratırken yaptığımız işlem (Creating a TextView from codebehind on Andriod)
TextView x = new TextView(this); // constructor'a context geçiliyor.
Çalışma zamanında reflection ile yukarıdaki olayın gerçekleştirilmesi: Runtime'da bir TextView nesnesi yaratırken yaptığımız işlem -Constructor'a ulaşmak- (Creating a TextView from codebehind at runtime with using reflection)
String x = TextView.class.toString().replace("class ", ""); Class<?> cls = Class.forName(x); Class<?> param[] = new Class[1]; param[0] = Context.class; //Context=o an ki context ==> [activity.class] Constructor<?> ct = cls.getConstructor(param); Object paramVal[] = new Object[1]; paramVal[0] = context; Object retobj = ct.newInstance(paramVal); //constructor'a context geçilerek TextView'ın yeni bir instance'ı yaratıldı.Çalışma zamanında reflection ile yarattığımız TextView nesnesinin setText() methoduna erişiyoruz (Reaching to setText() method at the runtime)
Class methodParam[] = new Class[1]; methodParam[0] = java.lang.CharSequence.class; Method method = cls.getMethod("setText", methodParam); Object arglist[] = new Object[1]; arglist[0] = new String("BU TEXTVIEW RUNTIME'DA OLUŞTURULDU"); method.invoke(retobj, arglist); //void method call edildi.
Bu aşama ve sonrasında yapılacaklar istenen şeye göre elbette değişkenlik arzedecektir, biz burada örnek olması açısından retobj isimli nesnemizi View'a cast ederek ilgili layout'a ekleyeceğiz. (The rest is up to you, I casted retobj to View and added it to a linearLayout as following to set an example)
View v = (View)retobj; linearLayout.addView(v);
İyi çalışmalar,
(Good work)
(Good work)
10 Aralık 2011 Cumartesi
Derinlemesine Android
Merhaba,
Bugün birer android geliştirici olarak kullandığımız bu platformun Türkçe kaynaklarda bariz eksikliğinin göründüğüne inandığım temellerine inmeye başlayacağız. Pek tabi konu Android'in temelleri olunca, ister istemez linux literatüründen de bazı kavramlara girmemiz kaçınılmaz olacak. Elimden geldiğince yalın dille anlatmaya çalışacağım bu yazı umuyorum tüm Android ile ilgilenen yazılımcı arkadaşlar için faydalı olur. Evet herşey hazırsa, kemerlerinizi takın ve arkanıza yaslanın keza android'in temellerine olan yolculuğumuz şu andan itibaren başlamak üzere.
Android; mobil cihazlar için geliştirilmiş, genel manada 4 farklı katmandan oluşan bir işletim platformudur. Bu katmanların en altında, platformun abstraction layer'ı olma görevini de üstlenecek şekilde konumlandırılmış olan linux kernel bulunmaktadır. HAL'de (hardware abstraction layer) linux kernel'in kullanılmasının temelde üç önemli amacı vardır.
Dalvik Virtual Machine (DVM)
Bugün birer android geliştirici olarak kullandığımız bu platformun Türkçe kaynaklarda bariz eksikliğinin göründüğüne inandığım temellerine inmeye başlayacağız. Pek tabi konu Android'in temelleri olunca, ister istemez linux literatüründen de bazı kavramlara girmemiz kaçınılmaz olacak. Elimden geldiğince yalın dille anlatmaya çalışacağım bu yazı umuyorum tüm Android ile ilgilenen yazılımcı arkadaşlar için faydalı olur. Evet herşey hazırsa, kemerlerinizi takın ve arkanıza yaslanın keza android'in temellerine olan yolculuğumuz şu andan itibaren başlamak üzere.
Android Stack Yapısı
Android; mobil cihazlar için geliştirilmiş, genel manada 4 farklı katmandan oluşan bir işletim platformudur. Bu katmanların en altında, platformun abstraction layer'ı olma görevini de üstlenecek şekilde konumlandırılmış olan linux kernel bulunmaktadır. HAL'de (hardware abstraction layer) linux kernel'in kullanılmasının temelde üç önemli amacı vardır.
- Fragmantasyonun android'de fazla olması (Andy Rubin'in belirttiğine göre her gün 500.000 yeni androidli cihaz piyasaya çıkmaktadır) ve linux kernel'in farklı donanımlarda kolayca compile edilebilmesi münasebetiyle yaşanması muhtemel uyum problemlerinin önüne geçmek. Bu sıkıntıyı gidermek maksadıyla bir çok farklı donanıma ait sürücülerin linux kernel içerisinde implemente edilmiş halde bulunduğunu söyleyebiliriz.
- Güvenlik, hız, proses ve network yönetimi konularında yadsınmaz başarısı.
- Linux kernel'in de hali hazırda açık kaynak olması.
Belirtmeden geçmeyelim, android linux kernel'i kullanmaktadır, linux değildir. Ayrıca linux'ın tüm standartlarını içermez. Bununla beraber Android için linux kernel'e ilave edilmiş alarm, power management, kernel debugger, low memory killer, ashmem, binder ve logger gibi nesneler mevcuttur. Bu noktada Binder'a biraz değinmekte fayda var; Android'de uygulamalar ve servisler ayrı prosesler üzerinde çalışırlar yani bir proses başka bir prosesin memory'sine erişemez ancak bunun yanında aralarında haberleşme ve data paylaşımına da ihtiyaç duyarlar. İşte Android'de iki proses arasında data aktarımını-mesaj gönderimini sağlayan yani interproses communication çağrıları (IPC Call) yöneten yapı Binder'dır.
İkinci katmanda, android geliştiricilerinin çok nadiren direk olarak erişmeye çalıştığı genel manada ise üst katmanların ihtiyaç duyacağı işlevselliklerin yerine getirilebilmesini sağlayacak kütüphanelerin (databasesel ilişkilerin yönetilmesine imkan veren sqlite, opengl için 2D-3D grafik işleme, bitmap ve vektör font render ederken kullanılan freetype, html render etmede kullanılan webkit gibi) implemente edildiği native libraries bulunmaktadır.
Android'de iki farklı prosesin birbirleriyle haberleşmesini Binder sağlar
İkinci katmanda, android geliştiricilerinin çok nadiren direk olarak erişmeye çalıştığı genel manada ise üst katmanların ihtiyaç duyacağı işlevselliklerin yerine getirilebilmesini sağlayacak kütüphanelerin (databasesel ilişkilerin yönetilmesine imkan veren sqlite, opengl için 2D-3D grafik işleme, bitmap ve vektör font render ederken kullanılan freetype, html render etmede kullanılan webkit gibi) implemente edildiği native libraries bulunmaktadır.
Dalvik Virtual Machine (DVM)
Android uygulamalarını compile ederken Android için özel olarak yazılmış Dalvik Virtual Machine kullanılır. Uygulamalar genellikle Java ile geliştirildiğinden, kodlar önce JVM (Java Virtual Machine) ile bytecode'a compile edilir (.java => .class). Bu işlem sonrası JVM ile uyumlu hale gelen .class dosyaları uygulama çalıştırılmaya başlamadan önce bir de Android'in anlayabileceği ve çalıştırabileceği Dalvik compiled executable file olan .dex formatına çevrilir. Aşağıdaki resimde, JVM ile çalışan cihaz ile Android arasındaki fark gösterilmektedir. Burada şu soruyu sorabilirsiniz "neden direk Dalvik byte code'a çevrilmiyor da önce Java byte code'a daha sonra Dalvik byte code'a çevriliyor?" Bu sorunun temelde iki nedeni var.
Dex dosyasının bir diğer oluşturulma amacı hafıza ve işlemci hızının daha optimum seviyelere indirgenmesinin sağlanmasıdır keza Dalvik Virtual Machine'in geliştiricisi Dan Bornstein 2008 yılında yaptığı bir sunumda %100 işlemci kaynaklarını kullanan sıkıştırılmamış (uncompressed) bir java kodunun, sıkıştırıldığında %56'lara, Dalvik'li sıkıştırılmamış halinin ise %48'lere kadar indiğini ifade etmiştir. Yani arada neredeyse yarı yarıya bir fark vardır ki bu bir çok açıdan sınırlı olan mobil cihazlar için çok önemli bir ayrıntıdır. Bu iyileştirmeyi sağlamada en büyük etkenlerden biri -DVM'nin JVM'den en büyük farkı olarak da gösterilmesine neden olan- önceden de belirttiğimiz gibi DVM'nin stack based yerine register based olarak geliştirilmesinde yatmaktadır.
Ayrıca JVM, aygıtın tipine bakmaksızın tüm cihazlar için bir tanedir (one size fits all). Yani bir mobil cihaz için kullanılan JVM ile mobil olmayan bambaşka bir cihaz (örneğin süper bilgisayar) için kullanılan JVM'de hiç bir farklılık yoktur. Bunun yanında DVM spesifik olarak mobil cihazlar için geliştirildiğinden JVM ile oluşan JAR dosyasından çok daha küçük ve mobil cihazın ihtiyaç duymayacağı (kaynak kod ile ilgili bir sürü gerekli gereksiz bilgi -verbose data- jar dosyasının içerisine yazılmaktadır) bilgilerin atılarak derlendiği bir dosya çıktısı oluşturmaktadır. Tüm bu teknik özelliklerin yanında Google'ı DVM'yi yazmaya iten nedenlerden bir diğeri de Oracle ile geçmişte yaşamış olduğu lisans problemleridir.
Hepimizin bildiği gibi Android bir açık kaynak kod geliştirme platformudur ve açık kaynak kod projelerinde, geliştiricilerin platformun tüm öğelerinden istedikleri miktarda erişim sağlaması birincil amaçtır. Bu amaç doğrultusunda, oldukça kapsamlı ve geniş kütüphaneler hazırlanarak kullanıcıların maksimum fayda edinebilecekleri bir altyapı oluşturulması önemlidir. Stack'te bulunan üçüncü kısım yani application framework (uygulama altyapısı) bu ihtiyaç için oluşturulmuştur. Application framework'te bulunan nesneler, geliştiricilerin native librarylere ulaşmasında kilit rol oynarlar. Bu nesneler, native'de bulunan kütüphane elemanlarıyla iletişime geçerek, normal şartlarda ancak taklalar atarak ulaşabileceğimiz bilgileri (örneğin bir koordinat bilgisi) son derece basit bir şekilde elde etmemize imkan verirler. Kısaca kodlarımızda kullandığımız neredeyse tüm nesneler burada bulunan nesnelerin soyutlandırılmış halleridir.
Yapının en üst bölümünde yazmış olduğumuz applicationlar (uygulamalar) bulunmaktadır. Application, bir veya birden çok apk (application package file) adı verilen paketlerin birleşiminden meydana gelir. Apk dosyaları .jar dosyaları gibi sıkıştırılmış dosyalardır. Android platformundaki yükleme ve dağıtım gibi işlevleri yerine getirdikleri için android'teki exe dosyaları şeklinde adlandırılabilirler. Apk dosyaları içerilerinde, yazmış olduğumuz kodları (ki bu kodlar apk oluşumu esnasında derlenerek dex formatına çevrilirler), resource, manifest, sertifika ve diğer uygulamayla ilgili tüm bilgileri barındırırlar.
Güvenlik
Android, Inter-Component Communication (Komponentler Arası İletişim) yapısına göre çalışır. Her komponent tipi sadece kendi tipindekilerle iletişime geçebilir ve yine her uygulama sadece kendisine atanan tekil bir kullanıcı kimliği aracılığıyla kendi linux prosesi üzerinde çalıştırılır. Bu sayede uygulamadan kaynaklanması muhtemel kusurlar nedeniyle oluşacak hasarlar önlenmiş olur. Yine her uygulama diğer uygulamalardan kendi izolasyonunu sağlamak amacıyla veritabanı ve diğer konfigürasyon arabirimlerinin belirtilmiş olduğu bir sandbox (çocuk parklarında çocukların güvenliğini sağlamak amacıyla oluşturulan kum havuzu gibi düşünebilirsiniz) dosya sistemine sahiptir. Bu izolasyon yapısı sayesinde, uygulama izin verdiğini belirtmedikçe asla diğer uygulamalar tarafından erişilemez. (Google mühendislerinden Dianne Hackborn'ün konuyla ilgili açıklaması: Android had a number of very different original design goals than iOS did. A key goal of Android was to provide an open application platform, using application sandboxes to create a much more secure environment that doesn’t rely on a central authority to verify that applications do what they claim. To achieve this, it uses Linux process isolation and user IDs to prevent each application from being able to access the system or other application in ways that are not controlled and secure. https://plus.google.com/105051985738280261832/posts/XAZ4CeVP6DC)
- DVM registerbased virtual machine JVM ise stack-based virtual machine'dir. Stack-based vmler register-based vmler'e göre ham kodu generate etmede daha hızlı ve kolaydırlar. Register-basedler ise yüksek ölçekte optimize edilmiş kodun generate edilmesinde ve hızlı implementasyon yaratımlarında daha başarılıdırlar. Dolayısıyla compile etme işleminin tekrar tekrar yapılması yerine önceden jvm ile makinenin anlayabileceği dile çok yakın şekilde çevrilmiş byte code'tan dvm'nin ürettiği dex tipine çevirim kullanılır.
- DVM, .NET framework'ün virtual machine'i olan CLR (Common Language Runtime) mantığında çalışır. CLR, IL (intermediate language) adında ara bir dil vasıtasıyla uygulamayı hem dilden hem de işletim sisteminden bağımsız hale getirir. DVM'de de mantık aynı şekildedir, her ne kadar teoride gibi gözükse de Phyton'la yazdığınız kodu dalvik ile compile edebiliyorsanız android bu uygulamanızı başarıyla çalıştırabilecek demektir.
Android'de java kodu 2 kere compile edilmiş olur
Dex dosyasının bir diğer oluşturulma amacı hafıza ve işlemci hızının daha optimum seviyelere indirgenmesinin sağlanmasıdır keza Dalvik Virtual Machine'in geliştiricisi Dan Bornstein 2008 yılında yaptığı bir sunumda %100 işlemci kaynaklarını kullanan sıkıştırılmamış (uncompressed) bir java kodunun, sıkıştırıldığında %56'lara, Dalvik'li sıkıştırılmamış halinin ise %48'lere kadar indiğini ifade etmiştir. Yani arada neredeyse yarı yarıya bir fark vardır ki bu bir çok açıdan sınırlı olan mobil cihazlar için çok önemli bir ayrıntıdır. Bu iyileştirmeyi sağlamada en büyük etkenlerden biri -DVM'nin JVM'den en büyük farkı olarak da gösterilmesine neden olan- önceden de belirttiğimiz gibi DVM'nin stack based yerine register based olarak geliştirilmesinde yatmaktadır.
Ayrıca JVM, aygıtın tipine bakmaksızın tüm cihazlar için bir tanedir (one size fits all). Yani bir mobil cihaz için kullanılan JVM ile mobil olmayan bambaşka bir cihaz (örneğin süper bilgisayar) için kullanılan JVM'de hiç bir farklılık yoktur. Bunun yanında DVM spesifik olarak mobil cihazlar için geliştirildiğinden JVM ile oluşan JAR dosyasından çok daha küçük ve mobil cihazın ihtiyaç duymayacağı (kaynak kod ile ilgili bir sürü gerekli gereksiz bilgi -verbose data- jar dosyasının içerisine yazılmaktadır) bilgilerin atılarak derlendiği bir dosya çıktısı oluşturmaktadır. Tüm bu teknik özelliklerin yanında Google'ı DVM'yi yazmaya iten nedenlerden bir diğeri de Oracle ile geçmişte yaşamış olduğu lisans problemleridir.
Hepimizin bildiği gibi Android bir açık kaynak kod geliştirme platformudur ve açık kaynak kod projelerinde, geliştiricilerin platformun tüm öğelerinden istedikleri miktarda erişim sağlaması birincil amaçtır. Bu amaç doğrultusunda, oldukça kapsamlı ve geniş kütüphaneler hazırlanarak kullanıcıların maksimum fayda edinebilecekleri bir altyapı oluşturulması önemlidir. Stack'te bulunan üçüncü kısım yani application framework (uygulama altyapısı) bu ihtiyaç için oluşturulmuştur. Application framework'te bulunan nesneler, geliştiricilerin native librarylere ulaşmasında kilit rol oynarlar. Bu nesneler, native'de bulunan kütüphane elemanlarıyla iletişime geçerek, normal şartlarda ancak taklalar atarak ulaşabileceğimiz bilgileri (örneğin bir koordinat bilgisi) son derece basit bir şekilde elde etmemize imkan verirler. Kısaca kodlarımızda kullandığımız neredeyse tüm nesneler burada bulunan nesnelerin soyutlandırılmış halleridir.
Yapının en üst bölümünde yazmış olduğumuz applicationlar (uygulamalar) bulunmaktadır. Application, bir veya birden çok apk (application package file) adı verilen paketlerin birleşiminden meydana gelir. Apk dosyaları .jar dosyaları gibi sıkıştırılmış dosyalardır. Android platformundaki yükleme ve dağıtım gibi işlevleri yerine getirdikleri için android'teki exe dosyaları şeklinde adlandırılabilirler. Apk dosyaları içerilerinde, yazmış olduğumuz kodları (ki bu kodlar apk oluşumu esnasında derlenerek dex formatına çevrilirler), resource, manifest, sertifika ve diğer uygulamayla ilgili tüm bilgileri barındırırlar.
Güvenlik
Android, Inter-Component Communication (Komponentler Arası İletişim) yapısına göre çalışır. Her komponent tipi sadece kendi tipindekilerle iletişime geçebilir ve yine her uygulama sadece kendisine atanan tekil bir kullanıcı kimliği aracılığıyla kendi linux prosesi üzerinde çalıştırılır. Bu sayede uygulamadan kaynaklanması muhtemel kusurlar nedeniyle oluşacak hasarlar önlenmiş olur. Yine her uygulama diğer uygulamalardan kendi izolasyonunu sağlamak amacıyla veritabanı ve diğer konfigürasyon arabirimlerinin belirtilmiş olduğu bir sandbox (çocuk parklarında çocukların güvenliğini sağlamak amacıyla oluşturulan kum havuzu gibi düşünebilirsiniz) dosya sistemine sahiptir. Bu izolasyon yapısı sayesinde, uygulama izin verdiğini belirtmedikçe asla diğer uygulamalar tarafından erişilemez. (Google mühendislerinden Dianne Hackborn'ün konuyla ilgili açıklaması: Android had a number of very different original design goals than iOS did. A key goal of Android was to provide an open application platform, using application sandboxes to create a much more secure environment that doesn’t rely on a central authority to verify that applications do what they claim. To achieve this, it uses Linux process isolation and user IDs to prevent each application from being able to access the system or other application in ways that are not controlled and secure. https://plus.google.com/105051985738280261832/posts/XAZ4CeVP6DC)
Her uygulama kendisine ait tekil bir kimlik bilgisi ile çalıştırılarak çevresinden izole edilmiş olur.
Android'de Başlangıç Mekanizması (Startup)
Aslında olan biteni şöyle bir analojiyle açıklayabiliriz; bir otel düşünün, içinde kalan her insan için ayrı bir oda tesis edilmiş olsun. Güvenlikten sorumlu bir otel görevlisi herkes için ayrı ayrı yetkilerinin yazılı olduğu bir yaka kartı hazırlıyor ve hazırlanan bu yaka kartlarının takılması zorunlu. İnsanlar birbirleriyle görüşmek istediğinde otel görevlisi görüşüp görüşemeyeceklerine bu yetki kartlarına bakarak onay veriyor ya da vermiyor.
Android: otel
Otel odaları: tekil proses idler
İnsanlar: uygulama ve komponentler
Güvenlikten sorumlu otel görevlisi: referans monitör
Yaka kartları: permission labels (yetki etiketleri)
Android'de Başlangıç Mekanizması (Startup)
- Bootloader linux kernel'i yükler ve init prosesi başlatır. (/system/init)
- Init, çoğu /system/bin adresinde bulunan, android native programda implemente edilmiş bazı servisleri (usbd [usb bağlantılarını yönetmek için], adbd [android debug bridge-adb bağlantılarını yönetmek için], debuggerd [dump memory gibi debug proses taleplerini yönetmek için], rild [radio interface layer daemon - radyo ile bağlantıyı yönetmek için], vold, netd, installd, qemud) başlatır. Yeri gelmişken belirtelim unix'te (veya multitask çalışan diğer işletim sistemlerinde) init aşamasında arka planda çalıştırılmaya başlanan servislere daemon denir ve genelde sona koyulan d ile belirtilirler.)
- Init, zygote (zigot) prosesi başlatır. Zygote classları yükleyen ve sanal makine için soketten gelecek istekleri dinleyen çekirdek prosestir. Aslında zygote'un yaptığı şey tüm uygulamaları çalışmaya hazır hale getirmektir şöyle ki; bir futbol takımında maç öncesi ilk 11'de oynasın oynamasın tüm futbolcular ısınır değil mi? Neden? Çünkü her an görev alma olasılığı mevcuttur. Aniden maçta oynanması istendiğinde hocam 2 dk bekleyin ben bir ısınıp geleyim dediğini düşünsenize. Zygote bu ısınma durumunu sağlar. Tüm uygulamaları, ileride çalışsın çalıştırılmasın farketmeksizin belli bir seviyeye kadar ayağa kaldırır (uykudan uyandırır, android uygulamayı çağırdığında gidip bir de onu uyandırmayla uğraşmaz).
- Init runtime prosesi, runtime proses de service manager'ı başlatır. Servis manager, uygulamanın ihtiyaç duyacağı servisleri yönetecek (TelephonyService, LocationService, vb), gerektiğinde yeni yazılan servisin kaydedileceği, gerektiğinde ise kullanılması gereken servisin çekilebileceği kısacası servislerle ilgili tüm içeriğin yönetiminin sorumlu olduğu yapıdır.
- Zygote dalvik vm'yi çalıştırmaya başlarken bir diğer yandan da kendisine system server'ın çalıştırılması yönünde bir istek yollanır, zygote system service için yeni bir sanal makine (vm) kopyalayarak (forking) servisi çalıştırır. Burada forking denen hadiseyi biraz açıklayalım; forking bir diğer anlamıyla daemonizing, programın yeni bir child proses ile arka planda yürütülmesi demektir. Linux'ta yeni bir proses yaratılmak istendiğinde fork() kullanılır. Mitoz bölünme gibi düşünebiliriz keza bütün proseslerin atası Init'tir. Son olarak ekleyelim fork() çalıştırıldığında kopyalanan proses önceki prosesin kaldığı yerden devam eder. Biraz daha basite indirgeyelim; bir proses var, bu prosesten başka bir proses oluşturulması veya bir diğer deyişle child'i oluşturulması gerekiyor ki bunu ancak fork() ile yapabiliyoruz. fork() geriye bir proses id dönüyor. Bu prosesId > 0 ise parent üzerinden işleme prosesId = 0 ise child üzerinden prosese devam ediliyor.
- System server, surface flinger ve audio flinger'ın bulunduğu native system serverları başlatır. Native sistem sunucuları sistem manager'a IPC servis hedefleri olarak kaydedilir. Bu andan itibaren, çalışma zamanı prosesi (runtime process, service manager, system server (sistem sunucusu) ve native sunucuların hepsi android'in native programı olarak implemente edilmiş olur.
- Sistem servisi (system service) window manager, activity manager, location manager gibi tüm yönetim işlemini üstlenen android managed services'i başlatır. Android managed services service manager'a kaydedilir.
yeşiller native kod tarafını, maviler java tarafını göstermektedir.
Etiketler:
abstraction layer,
apk,
application framework,
binder,
dalvik,
dalvik virtual machine,
dex,
dvm,
güvenlik,
Inter-Component Communication,
ipc,
jvm,
linux kernel,
native library,
security,
stack
Kaydol:
Kayıtlar (Atom)