좋은 자료들을 찾아서 참고 겸 올려둔다.


버전(Version)을 제대로 이해하기


브랜치의 종류

'프로젝트' 카테고리의 다른 글

[UML] Use Case Diagram  (0) 2017.04.12
[C++] Qt 를 이용한 타이머 만들기  (0) 2017.01.24
블로그 이미지

NCookie

,

회사에서 C 코드를 안드로이드에서 사용해야할 일이 있어서 NDK와 JNI에 대해 알아보고 있었다. 그러다보니 자연스레 아키텍쳐까지 보게 되었다. 좋은 현상인 것 같다.




Linux Kernel


Android 플랫폼은 리눅스 커널을 기반으로 한다. 


오디오, 키패드, 카메라 등 각종 장치의 사용을 위한 드라이버와 프로세스 관리, 메모리 관리 등의 기능을 포함하고 있다.


리눅스 커널은 오픈 소스이면서 드라이버 모델의 검증된 안정성, 최신 장비의 지원, 하드웨어 입출력에 대한 보안모델 제공 등이 안드로이드가 리눅스 커널을 사용하는 이유일 것이다.


안드로이드서 사용하는 리눅스 커널은 알람, 공유메모리, Low memory-killer, kernel debugger, binder, power management, logger 등 기존에 없었거나 향상된 기능들이 있다.



Hardware Abstraction Layer(하드웨어 추상화 계층)


커널의 윗단에는 C와 C++로 짜여진 시스템 라이브러리가 존재한다. 기존에 많이 사용되어 신뢰성을 보장한다.


Java API 프레임워크에 하드웨어 기능을 노출하는 표준 인터페이스르 제공한다. 카메라 또는 블루투스 모듈과 같은 특정 유형의 하드웨어 구성 요소를 위한 인터페이스를 구현한다.


프레임워크 API가 기기 하드웨어에 액세스하기 위해 호출을 수행하면 안드로이드 시스템이 해당 하드웨어 구성 요소에 대한 라이브러리 모듈을 로드한다.


이러한 라이브러리에는 System C Library, Media Libraries, Surface Manager, 3D Libraries 등이 있다.



Android Runtime


안드로이드 버전 5.0(API 레벨 21) 이상부터는 각 앱이 자체 프로세스 내에서 자체 ART(Android 런타임) 인스턴스로 실행된다. 


ART의 주요 기능 중 몇 가지를 살펴보면 다음과 같다.


- AOT(Ahead of Time) 및 JIT(Just In Time) 컴파일

- 최적화된 가비지 컬렉터(GC)


이전에는 Dalvik VM이라는 것이 사용되었는데, 이 VM의 한계를 해결하기 위해 개발된 런타임이 ART이다. 


SUN의 자바는 명령들이 전부 8비트 길이를 가지지만 안드로이드는 4바이트이다. 기존의 SUN은 명령어가 스택에 들어가기 때문에 PUSH, POP명령어를 쓰고 Dalvik은 뱅크드레지스터를 이용한 복사명령을 이용하고 레지스터에서 바로 실행시키기 때문에 속도가 더 빠르다. 4바이트가 레지스터에 전부 들어가기 때문에 낮은사양에서도 느려지지 않는 효과도 있다. 



JNI


프로그램동작은 자바코드이고 드라이버들은 대부분 C/C++이지만 그 사이에 JNI가 있기때문에 동작이 가능하다. JNI는 자바코드에서 C나 C++  라이브러리를 호출할 수 있도록 만들어진 규약이다. 안드로이드에서 응용프로그램은 C/C++로도 만들 수 있다. 대신 UI를 가지기는 힘들다. 백그라운드 서비스를 제작할 경우 굳이 자바로 할 필요는 없다.



Native C/C++ Libraries


ART 및 HAL 등의 많은 핵심 Android 시스템 구성 요소와 서비스가 C 및 C++로 작성된 네이티브 라이브러리를 필요로 하는 네이티브 코드를 기반으로 빌드되었다. Android 플랫폼은 Java 프레임워크 API를 제공하여 이러한 일부 네이티브 라이브러리의 기능을 앱에 노출한다. 예를 들어, Android 프레임워크의 Java OpenGL API를 통해 OpenGL ES에 액세스하여 앱에서 2D 및 3D 그래픽을 그리고 조작할 수 있는 지원 기능을 추가할 수 있다.


C 또는 C++ 코드가 필요한 앱을 개발하는 경우에는 Android NDK를 사용하여 네이티브 코드에서 직접 이러한 몇몇 네이티브 플랫폼 라이브러리에 액세스할 수 있다.



Java API Framework


안드로이드 앱 개발을 하면서 가장 많이 접했던 계층이다. 뷰 시스템, resource manager, notification manager, activity manager, content provider 등을 호출하여 사용할 수 있다.


개발자는 안드로이드 시스템 앱이 사용하는 것과 동일한 프레임워크 API에 대한 전체 액세스 권한을 가진다.



System Apps


우리가 실행하고 사용하는 앱이다. 


시스템 앱은 사용자를 위한 앱으로도 작동하고 개발자가 자신의 앱에서 액세스할 수 있는 주요 기능을 제공하기 위한 용도로도 작동한다. 예를 들어, 앱이 SMS 메시지를 제공하고자 할 경우 해당 기능을 직접 빌드할 필요가 없다. 그 대신, 이미 설치된 SMS 앱을 호출하여 지정한 받는 사람에게 메시지를 제공할 수 있다.



JIT와 컴파일러, NDK 등에 대해서는 다른 글에서 다루도록 하겠다.



참고


플랫폼 아키텍쳐


안드로이드의 구조


안드로이드 가상머신 동작 구조


안드로이드 구조와 원리 정리

블로그 이미지

NCookie

,

java.lang.NoSuchMethodError: No static method getFont(Landroid/content/Context;ILandroid/util/TypedValue;ILandroid/widget/TextView;)


이런 오류가 떴는데 도대체 뭐가 문제인지 모르겠어서 검색해봤다.


dependency와 빌드 툴의 버전이 맞지 않아 발생할 수 있다고 한다.


나는 RecyclerView를 사용했는데, 버전을 확인해보니 혼자 27.0.1이었다. 그래서 빌드 버전인 26.1.0으로 바꾸어줬더니 깔끔하게 해결되었다.



참고


java.lang.NoSuchMethodError: No static method getFont(Landroid/content/Context;ILandroid/util/TypedValue;ILandroid/widget/TextView;)


Error get Font Landroid/content/Context;ILandroid/util/TypedValue

'안드로이드' 카테고리의 다른 글

안드로이드 이미지 여백  (0) 2017.12.05
안드로이드 플랫폼 아키텍쳐  (0) 2017.11.30
안드로이드 리소스 ID  (0) 2017.11.27
serializable, parcelable  (0) 2017.11.24
안드로이드 Bundle  (0) 2017.11.24
블로그 이미지

NCookie

,

xml에서 레이아웃을 작성할 때 사용하는 그 android:id="@android:id/" 가 지금 설명하려는 것이다.


이 ID는 xml에 정의된 고유 ID 뿐만 아니라 어플리케이션에서 결과 코드값으로도 사용할 수 있다.


선언 방법은 간단하다.


res/values/ids.xml 에서 아래와 같은 형식으로 적어주면 된다.


<?xml version="1.0" encoding="utf-8"?>
<resources>
   
<item type="id" name="button_ok" />
   
<item type="id" name="dialog_exit" />
</resources>

resource는 무조건 root에 있어야 하며, item 태그는 value를 가지지 않고 속성만을 가지고 있다. type은 항상 "id" 이어야하고 name은 ID에 붙이고 싶은 이름을 넣으면 된다.


<Button android:id="@id/button_ok"
   
style="@style/button_style" />


그리고 위와 같이 레이아웃 등에서 사용할 수 있다.


이런 것들은 굳이 ids.xml에 선언하지 않아도 원하는 레이아웃에서 직접 ID를 설정할 수 있다. 그렇다면 왜 굳이 이런 번거로운 방법을 사용하는걸까.


ids.xml에는 모든 ID가 선언되어 있기 때문에 컴파일러는 그것들을 recognize 할 수 있다.


<TextView
    android:id="@+id/text1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignBelow="@id/text2"
    android:text="...."/>
<TextView
    android:id="@+id/text2"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="...."/>


text2라는 ID를 가진 뷰가 선언되기 전에 text2를 text1에서 참조하였기 때문에 에러가 발생한다. 이 때 ids.xml에 ID들을 미리 선언해둔다면 이러한 에러를 피해갈 수 있다.


이런 예시도 있다. 대형 프로젝트의 경우, id를 굉장히 많이 선언하게 되는데. 만약 중간에 View 하나를 삭제했다면 컴파일러는 no such field 같은 오류를 뿜을 것이다. 하지만 이런 오류 메시지 하나만으로는 그 많은 소스 코드에서 어떤 것이 문제인지 모를 수도 있다.


하지만 만약 ids.xml에 id들을 선언해놓는다면, 이 에러는 피해갈 수 있을 것이다.(이게 최고의 해결방법인지는 모르겠지만)



어쨌든 지금 분석하고 있는 nRF Toolbox 라는 어플리케이션의 코드에서는 ids.xml이라는 것을 사용한다. 난 그것과 관련된 오류 때문에 이 자료들을 찾아봤고.


...그냥 그렇다고.



참고


More Resource Types - ID(Google Developers)


what is ids.xml used for?

블로그 이미지

NCookie

,

액티비티에 객체를 전달하기 위해서는 이전에 다루었던 Intent와 Budnle을 사용해야 한다.


Bundle은 객체를 직렬화하여 저장하는데 serializble과 parcelable이라는 두 가지 방법이 있다.


이 둘은 뭐가 다른걸까. 둘 다 똑같이 객체를 직렬화한다. Serializable 또는 Parcelable 클래스를 implements 하여 클래스를 선언해야 하는 것도 같다. 다른 것은 성능과 사용 방법이다.



Serializable을 사용하는 방법은 간단하다. 클래스를 선언할 때 Serializable 클래스를 implements 하기만 하면 된다.


Serializable은 marker 인터페이스이기 때문에 implement 해야할 메소드도 없기 때문에 사용하기 엄청 편리하다. 대신 메커니즘이 많은 임시 객체를 생성하기 때문에 성능 저하를 일으킨다.



Parcelable은 이 반대다. 꽤나 많은 양의 boilerplate 코드가 있어 가독성이 떨어지고 유지보수가 어려워진다. 그 대가로 빠른 속도를 얻는다.



자세한 성능 비교는 Parcelable vs Serializable 에서 볼 수 있다. 


어쨌거나 결론은 Serializable을 많이 사용한다는 것이다. 성능이 떨어진다고 해도 Parcelable에 비해 딸린다는 것이지, 심각할 정도로 차이가 나는 것은 아니기 때문이다.



참고


14. Activity에 대해서 - 객체 직렬화편(Serializable)


Parcelable vs Serializable

'안드로이드' 카테고리의 다른 글

안드로이드 java.lang.NoSuchMethodError: No static method getFont  (0) 2017.11.28
안드로이드 리소스 ID  (0) 2017.11.27
안드로이드 Bundle  (0) 2017.11.24
안드로이드 Deprecated  (0) 2017.11.23
FLAG_ACTIVITY_NEW_TASK  (0) 2017.11.23
블로그 이미지

NCookie

,