# Docker 기반 Android Jenkins CI (Mac 환경)

 

1. docker 설치 및 실행

    - https://hub.docker.com/editions/community/docker-ce-desktop-mac


2. jenkins docker 이미지 다운로드 및 실행

$ docker pull jenkins/jenkins:lts

$ docker run -d -p 8080:8080 --name jenkinsCI jenkins/jenkins:lts


    - "-d" : 데몬으로 실행. 없으면 shell 종료시 같이 꺼짐.
    - "-p 8080:8080" :  포트 구성

    - "--name jenkinsCI" : 컨테이너 이름

    - "jenkins/jenkins:lts" : 받아놓은 lts 버전, 없으면 받아온다. - https://hub.docker.com/r/jenkins/jenkins/


3. jenkins local 접속 및 기본설치

    - localhost:8080 으로 접속

    - 첫 인증코드를 확인하기 위해 jenkinsCI의 log를 확인

docker logs jenkinsCI

    - 플러그인 설치
    - 사용자 계정 등록


4. docker 이미지에 Android SDK 설치

    4-1. docker shell에 접속     

$ docker exec -u 0 -it [Container ID] /bin/bash

 

    4-2. Android-SDK 기본 설치

$ apt update

$ apt install android-sdk


    4-3. 빌드에 필요한 Android-SDK tool 추가설치
        4-3-1. sdkmanager 설치

$ wget https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip

$ mv sdk-tools-linux-4333796.zip /usr/lib/android-sdk/sdk-tools-linux-4333796.zip

$ unzip sdk-tools-linux-4333796.zip


    4-3-2. sdkmanager로 필요한 tool 설치

$ cd tools/bin

$ ./sdkmanager --list

$ ./sdkmanager "build-tools;28.0.2" "build-tools;28.0.3" "platforms;android-28"


5. Jenkins 환경변수에 ANDROID_HOME path 등록

    - Jenkins 관리 > 시스템 설정 > Global properties > Environment variables
    - 이름: ANDROID_HOME, 값: /usr/lib/android-sdk

# Jenkins in Docker in ubuntu 18.04


노트북을 서버로 만들고 싶은 마음은 없어서 Jenkins를 Docker위에 올렸고 그 과정을 기록해 둔다.


1. Docker 설치

2. Docker용 Jenkins 설치

3. Docker로 Jenkins 띄우기

4. Docker로 Jenkins 운영



1. Docker 설치

    1) Docker CE VS Docker EE

        - CE : Community Edition ==> 선택

        - EE : Enterprise Edition


    + Ubuntu 환경: https://docs.docker.com/install/linux/docker-ce/ubuntu/

        1) 소스로 부터 설치: (좀 복잡하지만) 다들 이렇게 쓴다고 설명이 되어있음. => 선택

        2) 패키지 설치: Docker 업그레이드 할때마다 패키지 설치해야 한다고 함.


    + Mac 환경: https://docs.docker.com/docker-for-mac/install/

        1) 패키지 설치: 이 방법만 제공  ==> 선택


2. Docker용 Jenkins 설치

    - https://hub.docker.com/r/jenkins/jenkins/

    $ sudo docker pull jenkins/jenkins:lts


    1) jenkins/jenkins:lts VS jenkins/jenkins

        - LTS : Long Term Support  ==> 선택

        - Default : latest


3. Docker로 Jenkins 띄우기

    1) 띄우기(로그로 찍어주는 Initial Password 물어볼 것임 끝난거 아님)

    $ sudo docker run -d -p 8080:8080 -v /jenkins:/var/jenkins_home --name jenkins -u root jenkins/jenkins:lts


    2) http://localhost:8080 으로 접속

        - 처음은 Initial Password 물어봄


    3) Initial Password 찾을 수 있게 로그를 찍게해서 찾고 입력하기

    $ sudo docker logs jenkins


    4) Jenkins 스스로 업데이트


    5) 화면 갱신 및 사용자 등록




# Reference

- https://docs.docker.com/install/linux/docker-ce/ubuntu/

- https://docs.docker.com/docker-for-mac/install/

- https://jojoldu.tistory.com/139

- https://www.leafcats.com/215

# Android Material Design 스크롤에 따라 상단이 접히고 나오는 레이아웃 구성과 역할


화면구성과 그 xml 선언의 관계를 연결해보았습니다.





실제와 다른 부분이 있다면 알려주세요.

적극적으로 검토하고 반영하겠습니다.



Reference

- https://material.io/develop/android/components/collapsing-toolbar-layout/

- https://github.com/chrisbanes/cheesesquare

# Android Material Design 사이드메뉴(햄버그 메뉴?) 레이아웃 구성과 역할


화면구성과 그 xml 선언의 관계를 연결해보았습니다.



실제와 다른 부분이 있다면 알려주세요.

적극적으로 검토하고 반영하겠습니다.



Reference

- https://material.io/develop/android/components/navigation-view/

- https://github.com/chrisbanes/cheesesquare

# Android 앱 소스 난독화/암호화(Obfuscation) 종류


"Proguard면 충분하지!" 하고 살았던 그동안의 시간을 반성한다.

난독화의 종류는 다양하며 Proguard는 그 중 극히 일부분만 혹은 거의 보호를 못한다고 봐야 된다.



# 소스 난독화/암호화 종류

1. Renaming: 식별자 전환. 클래스/메소드의 이름을 a, b, c... 등 의미없는 이름으로 대체

2. Control Flow: 제어흐름 변환. A->B 와 같던 실행순서를 A->C->B 처럼 C구문을 삽입하는 기법

3. String Encryption: 문자열 암호화. 문자열을 암호화된 문자열로 대체하고 사용시 이를 치환

4. API Hiding: API 은닉. 특정 라이브러리 또는 메소드 호출을 Reflection으로 대체하여 숨긴다.

5. Class Encryption: 파일내용 전체를 암호화하여 저장해 두었다가 동적으로 복호화, 클래스 로더로 로딩



# 안드로이드 

6. DEX Encryption: Dalvik Executable 파일 자체를 암호화 한다.



난독화를 직접 할 수도 있다지만

아래와 같이 Proguard는 식별자 변환만 하고 나머지 툴은 모두 유료다.


 

 Proguard(무료)

DashOPro(유료)

Allatori(유료)

 DexGuard(유료)

 Renaming

O

O

O

O

 Control Flow

X

O

O

O

 String Encryption

X

O

O

O

 API hiding

X

X

X

O

 Class Encryption

X

X

X

O

 DEX Entryption

X

X

X

X






Reference

- Kim Jiyun, Go Namhyeon, Park Yongsu, A Code Concealment Method using Java Reflection and Dynamic Loading in Android, Journal of the Korea Institute of Information Security and Cryptology, Volume 25, Issue 1,  2015, pp.17-30

# Android 앱 Decompiling & Repackaging


Compiling이 된다는 것은 Decompiling(역공학/Reverse Engineering)이 존재한다고 봐야하며

decompiled 결과물의 완성도에 따라 흔히들 된다 안된다고 언급되는 것 같다.


0. 준비물

  1. apktool: https://ibotpeaches.github.io/Apktool/
    • APK를 decompiling/repackaging 할 도구이다.
    • dex -> smali코드 로 decompiled 되는데 변수명이 기계어 수준이고 가독성이 떨어진다.
      하지만 부분부분씩은 읽고 수정할 수 있다.

  2. dex2jar + jd-gui 혹은 jadx
    • APK를 decompiling하여 Java코드 수준으로 해석해주며 읽는 용도로 사용할 것이다.

  3. zipalign
    • 메모리 사용량 개선을 위해 4바이트 정렬을 시켜주어야 한다.

  4. apksigner
    • repackaged APK는 signing이 풀려있기 때문에 다시 해야한다.
    • zipalign 이후에 한다.
    • jarsigner를 사용해도 되지만 그 경우 zipalign보다 먼저 해야한다.



1. Decompiling

  1. $ apktool d [APK명]
    • 폴더내에 apk가 풀리고 dex대신 smali 폴더가 생긴다.

  2. smali 폴더에 있는 smali 코드 파일들을 찾아 수정한다.
    • 이때 smali 코드의 해석을 쉽게하기 위해 dex2jar + jd-gui 혹은 jadx를 참조한다.


2. Repackaging

  1. $ apktool b [APK명]
    • 폴더내에 있던 구성요소와 smali 파일들이 APK로 만들어진다.

  2. $ zipalign -v 4 [source APK명] [destination APK명]
    • 메모리 사용량 개선을 위해 4바이트 정렬을 시켜주어야 한다.

  3. $ apksigner sign --ks [key명].keystore [APK명]
    • repackaged APK는 signing이 풀려있기 때문에 다시 해야한다.





Reference

- https://developer.android.com/studio/command-line/zipalign

https://ibotpeaches.github.io/Apktool/





# [Android Auto] VS Apple CarPlay 기능 알아보기


1. Android Auto는 무엇?

  • Android Phone이 자동차의 dashboard에 연결되어(USB) 아래와 같은 화면이 나오면서 동작하는것.

출처: https://www.android.com/auto/


  • 비교대상으로 Apple 진영에서의 CarPlay를 예로 들 수 있다.

출처: https://www.apple.com/kr/ios/carplay/




2. 차량의 기능지원여부

  • Android Auto: 외국 2015년 8월 부터 출시.1) 국내 2018년 7월에 정밀지도 문제로 카카오내비를 허용하여 출시.2) 기본은 Google Map
  • Apple CarPlay: 국내외 2014년 3월 부터 출시.3)

따라서 그 이후에 출시한 차는 대부분 이러한 기능이 고려되어 있는 상태. 차량 제조사의 업데이트에 의해 지원 가능하기도 하다.

그런데 왜 CarPlay는 그동안 지도문제가 없었을까?

기사상으로는 지도 해외반출 이슈, 주요 기밀시설 가리기 이슈 등 Google의 정책요인에 기인한 것으로 확인되고 있음.4)



3. Phone의 기능지원여부



4. 차량 Dashboard와 연결
  • Android Auto: 연결 전 Android Auto App. 설치해야 함. USB연결 필요.
    • Dashboard <-> Android device (Android Auto App. <-> Calling, Messaging, Navigating and etc)
  • Apple CarPlay: USB만 연결하면 끝.
    • Dashboard  <-> iOS device



5. Android Auto 주요기능

  • Stand-alone: Dashboard에 연결없이 Android Auto App.만으로 실행가능
  • Google Assistant: 음성명령
  • Navigation: 길안내. 한국은 카카오네비 지원(2018.07 기준)
  • 전화
  • 문자 읽어주기, 받아적기, 보내기
  • 음악 검색, 재생
  • 기타 자동차 제조사 앱 기능들


6. Apple CarPlay 주요기능

  • Siri: 음성명령. Setting에서 Siri 활성화 해야함
  • Navigation: Apple 지도
  • 전화
  • 문자 읽어주기, 받아적기, 보내기
  • 음악 검색, 재생
  • 책 읽어주기
  • 기타 자동차 제조사 앱 기능들


7. Android Auto외의 다른 방법들

  • Mirrorlink:
    • CCC5) 에서 만든 Car-Smart-phone 표준규격
      • IVI(In Vehicle Infortainment) 에 화면을 복제하는 방식
      • 차량의 정보를 받아 올 수도 있다.
    • Android만 지원함
      • Dashboard <-> Android device (Android MirrorLink 지원 App. <-> 연계하는 앱)


Reference:

1) 관련기사: https://android-developers.googleblog.com/2015/08/announcing-android-auto-desktop-head.html

2) 관련기사: http://www.yonhapnews.co.kr/bulletin/2018/07/10/0200000000AKR20180710115900017.HTML

3) 관련기사: https://www.apple.com/kr/newsroom/2014/03/03Apple-Rolls-Out-CarPlay-Giving-Drivers-a-Smarter-Safer-More-Fun-Way-to-Use-iPhone-in-the-Car/

4) 련기사: http://news.mt.co.kr/mtview.php?no=2016092818070804379

5) Car Connectivity Consortium: https://mirrorlink.com/about%20ccc

   - https://www.carwow.co.uk/guides/buying/what-is-mirrorlink

# Wrap-up "Kotlin for Android Developers" at Udacity

Personally, I want to wrap-up the course to make a summary

- Link: https://www.udacity.com/course/kotlin-for-android-developers--ud888


I learned Kotlin for Android quickly with example.

I don't think this course shows all of Kotlin.

But it's effective to learn some important points and functions in Android Studio.



1. Import Kotlin plugin in the project

    - Menu > "Tools" > "Kotlin" > "Configure Kotlin in project" > "Android with Gradle"

       This function modifies gradle files to add Kotlin plugin.

    - Result: https://github.com/ndukwon/kotlin-notepad/commit/9484b0a9e04b95242544b2a83ca656ab64476114



2. Convert Java file to Kotlin file

    - Menu > "Code" > "Convert Java File to Kotlin File"

       This function converts a Java file to a Kotlin file.

    - Result: https://github.com/ndukwon/kotlin-notepad/commit/f61f09a603b02dcd15bd51deb78fef699fc5181a

      This case is lucky. Normally, there are some errors about

        + Nullable check

        + Lambda conversions

        + other non-standard Java features



3. Use SAM Conversions

    - SAM: Single Abstract Method

    - Methods like "View.OnClickListener.OnClick()" can be applied.

      ex) fab.setOnClickListener { startActivity(CreateActivity.get(this@MainActivity)) }

    - Result: https://github.com/ndukwon/kotlin-notepad/commit/ad3637101c5f8458187563e43fb548a39e819f96



4. Access views directly without "findViewById()"

    - Add "kotlin-android-extensions" plugin to support this

    - Import "kotlinx.android.synthetic.~~"

        ex) import kotlinx.android.synthetic.main.activity_main.*

              You can have direct accesses the views in "R.layout.activity_main".

    - Result: https://github.com/ndukwon/kotlin-notepad/commit/ad3637101c5f8458187563e43fb548a39e819f96



5. Convert Java's "switch" to Kotlin's "when"

    - "when" looks like "switch" without typing "case" keyword

       and supports

        + string comparison

        + "is" keyword

        + return value

    - Result: https://github.com/ndukwon/kotlin-notepad/commit/ad3637101c5f8458187563e43fb548a39e819f96



6. Insert a method/variable in the class

    - "kotlin-android-extensions" can make extension codes simple.

       In compile time, static method/variable is inserted for this.

        ex) val Context.layoutInflater get() = LayoutInflater.from(this)

             ==> So, we can use this like this.

            val view = context.layoutInflater.inflate(R.layout.item_note, parent, false)

    - Result: https://github.com/ndukwon/kotlin-notepad/commit/fb586664b645c847e79678b81dc4741fa2e5e2c3



7. Use "data class" instead of just "class"

    - to support automatically

        + Identity: equal()

        + Copy: copy()

        + Hash

    - Result: https://github.com/ndukwon/kotlin-notepad/commit/47aeae37c7488b7577bc7a5713a83753ed31f534



8. Add Anko library

    - Anko library contains a lot of helpers for Android SDK.

      In this trial, we will use "doAsync()" instead of "AsyncTask"

    - Result: https://github.com/ndukwon/kotlin-notepad/commit/ec2d1fc3a3faa520f3d3b2c71b063bfb03af5a61



9. Use "doAsync(): instead of "AsyncTask"

    - handles thread pooling and execution

        ex) doAsync { runnable.run() }

   - Result: https://github.com/ndukwon/kotlin-notepad/commit/e28010bf0514844d5455daccbd0febcf7031f5ba



10. Apply "lateinit" keyword

    - to initialize it by the time to be used

        ex) lateinit var notes: NoteDatabase

    - should not be nullable: cleaner and safer

    - Result: https://github.com/ndukwon/kotlin-notepad/commit/e28010bf0514844d5455daccbd0febcf7031f5ba



11. Add "@JvmStatic"

    - to help Java file understand getter/setter will be generated automatically

    - more: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-static/index.html

    - Result: https://github.com/ndukwon/kotlin-notepad/commit/e28010bf0514844d5455daccbd0febcf7031f5ba



To be updated....




Reference:

https://www.udacity.com/course/kotlin-for-android-developers--ud888

- https://thdev.tech/kotlin/2016/08/02/Basic-Kotlin-01.html

Process와 Thread의 비교


1. 개념이 다르다: Process는 Thread의 상위개념이다.


- Process가 생성된다는 것은 1개의 Process와 그 안에 1개의 Thread 가 생성되는 것.

- Multithreaded process는 이 안에 Thread가 여러개 생성될 수 있다는 것.

- 따라서 차이는 Single Thread process와 Multi Thread process를 비교하는 것이 효과적이다.



2. Memory 구성의 차이

출처: https://randu.org/tutorials/threads/

- Process는 개별적 Kernel, Code, Data, Heap, Stack 영역을 가지고 있다.

   대부분의 OS에서 Inter-Process Communication(IPC혹은 RPC)을 지원하여 Shared memory를 통해서 Process간의 제한적인 공유가 가능하다.

- Thread는 개별적 Stack, Register, PC등을 가지고 있다. 나머지는 Process의 것을 공유한다.



2-1. Process Memory 구성(Linux)


Kernel space: Kernel을 위한 영역으로 물리주소와의 매핑하며 언제든지 Switching이 일어날 수 있도록 준비하는 영역이다.

   user mode로는 접근할 수 없는 영역, 보통 설명시 생략된다.

Text(Code) Segment: 실행하는 코드를 저장하는 영역(bin을 올린다.)

- Data, BSS Segment: 전역변수/상수 등을 저장, 보통 통틀어 Data영역으로 부른다.

   구분하자면  Data - 초기화된 변수들, BSS - 초기화되지 않은 변수들

Heap: 동적할당된 부분 저장

Stack: ??  UNIX는 각 Thread의 stack을 여기에 할당해주는 것으로 보임.



2-2. Thread Memory 구성(POSIX)

Stack: Thread만의 지역변수, 매개변수, 리턴값을 저장.

  Windows - Virtual Memory에 할당

  UNIX - Process stack에 할당

  LINUX - ?? 커널이 할당해줌

Stack pointer

Program Counter(PC)

Registers: ?? CPU에 등록되는 그 레지스터를 의미하는지 잘 모르겠음

- 나머지는 Process 자원을 공용



2. 실행의 차이

- 기본적으로 OS는 Process단위로 스케줄링을 한다.

   따라서 User Level Thread(ULT)들은 Process가 block되면 모두 block된다.

- Kernel Level Thread(KLT)의 경우는 ULT보다 비용은 비싸지만 독립적 실행이 가능하다.

  따라서 Kernel-supported-threads 혹은 lightweight process라고 부르기도 한다.



3. Process보다 Thread를 쓰는 장점

- Process를 만들고 종료하는 것보다 Thread로 하는 것이 더 빠르다.

- Thread가 Context switching이 빠르다.

- IPC 통신을 하지 않아도 된다.

- 자원의 효율적 사용



3-1. Thread를 써서 장점을 보는 예

- 화면과 Background를 나누어 실행

- 주기적 백업 실행

- 파일을 나누어 읽기



4. Thread보다 Process를 쓰는 장점(Thread 단점)

- Thread를 많이 생성하면 오히려 저하가 일어날 수 있다.

- Single processer에서는 효과를 기대하기 어렵다.

- Thread는 디버깅이 어렵다.



Reference:

- Operating Systems Internals and Design Principles - William Stallings

- http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/

- https://computing.llnl.gov/tutorials/pthreads/

- https://randu.org/tutorials/threads/

- https://www.tutorialspoint.com/operating_system/os_multi_threading.htm

- http://sfixer.tistory.com/entry/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%ADcode-data-stack-heap

- http://lalwr.blogspot.kr/2016/02/process-thread.html

+ Recent posts