Why? 왜 우분투에서 안드로이드 앱 개발을 해야할까?
    1. 윈도우 보다는 안드로이드 개발하기가 편하다.
      이유 : 윈도우에서 안드로이드폰을 테스트하기 위해서는 USB 드라이버를 제조사별로 설치해야 한다.
        -> 우분투에서는 android용 rule.set만 설정해주면 된다.
    2. 무료로 사용할 수 있는 안정적인 리눅스 운영체제이다.
    3. 개발 중에 필요한 서버테스트 환경 등을 손쉽게 구축할 수 있다.



  적어도 안드로이드 앱 개발자에게는 윈도우보다는 나은 환경을 제공한다(맥북에서 써보니까 맥북도 괜찮다. 하지만, 맥북을 사야한다. 우분투는 지금 쓰는 노트북의 운영체제를 밀고 설치하면 된다).
  우분투에서 안드로이드 앱 개발환경을 구축하기는 쉽다.


1. JDK 설치하기
    1.1. JDK 설치 여부 확인
        - honeymon$ java -version
            = 설치되어 있는 경우 : 2.1.로 넘어가자.
            = 설치되어 있지 않은 경우 : 1.2.로 넘어가자.
    1.2. JDK 설치하기
        - JDK 중 하나를 선택하자.
            = OpenJDK(참조하는 라이브러리에서 오류가 발생한다고 합니다. 다른 분들은 이걸 비추.)
            = SunJDK(많은 분들은 이걸 추천합니다.)
            = IBMJDK 듣보잡!
        - JDK를 설치하기
            = sudo apt-get install sun-6-jdk
            = 설치 완료 확인 : java -version
2. Android SDK 설치하기(ADK -> Android SDK로 변경)
    2.1. 구글 안드로이드 개발 사이트 : http://developer.android.com/index.html
        - 우분투용 Android SDK를 다운로드 받는다
            = Android SDK url : http://developer.android.com/sdk/index.html
            ** i386이라고 되어있지만 아키텍쳐(32bit/64bit)는 크게 신경쓰지 않아도 된다.
        - Android SDK를 지정한 위치에 푼다.
            = honeymon : /home/honeymon/Dev/android-sdk 에 설치함
    2.2. Android SDK가 설치된 경로(PATH)를 .bashrc 에서 설정해준다.
        - 설정 이유 : adb, ddms와 같은 안드로이드를 다루는데 필요한 커맨드를 실행할 수 있도록 해주는 것이다.
        - Tip. 윈도우에서는 1개의 경로가 끝나면 끝에 ;(세미콜론)을 붙이지만, 유닉스와 리눅스에서는 :(콜론)을 사용한다.
          = 윈도우 사용자가 유닉스나 리눅스 환경에서 낯설어하는 부분 중 하나다. 윈도우가 유닉스를 따라한 것이다. 모든 운영체제의 시작은 유닉스였다고 보면 된다.

설정방법 :
  .bashrc 제일 마지막 문장에 PATH 추가

ANDROID_PATH=/home/honeymon/Dev/android-sdk
PATH=$PATH:$ANDROID_PATH/bin

    2.3. Android SDK 경로설정이 완료되었는지 확인한다.
        - adb help
3. Eclipse 설치하기
    3.1. Eclipse DownLoad site : http://www.eclipse.org/downloads/
        - Eclipse IDE for Java Developers 가 안드로이드 앱 개발에는 더 적합해 보인다.
        - 내가 처음에 배울 때는 Eclipse classic 을 추천받았었는데...
    3.2. Eclipse의 압축을 푼다.
    3.3. eclipse.ini 환경을 설정한다.
        - 개발에 적합한 것들과 설정했을 때 관련이 있는 것을 알려준다.
    3.4. eclipse를 설치한다.
4. ADT 플러그인 설치하기
    - 참고 사이트 : http://developer.android.com/sdk/eclipse-adt.html
    4.1. eclipse adt update site 추가 : https://dl-ssl.google.com/android/eclipse/
    4.2. Update 목록에 나온 플러그인을 선택하고 설치한다. 설치 완료 후 이클립스 재시작
    4.3. android Manager에서 ADK의 위치를 설정한다.
    4.4. 개발하려고하는 android 버전의 라이브러리를 확인한다.
        - 다운로드 속도가 느린 편이므로 마음의 여유를 가지고 임하자.
    4.5. 라이브러리 다운로드가 완료된 후 이클립스를 다시 시작한다.
5. ADT 설치확인
    5.1. Android manager를 선택한다.
    5.2. Android Emulator를 추가한다.
    5.3. Android Emulator를 실행한다.
    5.4. DDMS perspective를 선택하여 화면전환 후 5.3.에서 실행한 에뮬레이터가 인식되는지 확인한다.
    5.5. 가볍게 화면을 캡쳐해본다.
6. Android Project 생성하기(맛뵈기)
    6.1. Android Project 추가
    6.2. 실행하기
        - Android Application 선택 -> 수행
    6.3. 5.3.에서 실행한 Emulator에서 실행되는지 확인하기
        - Emulator가 동작하는데 걸리는 시간은 실제 안드로이드가 실행되는 시간보다 오래걸린다.
        - CPU의 성능에 따라서 그 차이가 제법 난다.
        - Emulator보다는 넥서스, 넥서스S, 넥서스 프라임과 같은 레퍼런스폰을 개발기기로 연결해서 테스트하는 것이 좋다.
    6.4. 실행시킨 에뮬레이터가 에뮬레이터에 보이면 정상적인 빌드 및 설치가 완료된 것이다.
7. 안드로이드 개발 Tip
    7.1. Java에 대한 공부는 꾸준하게 한다.
    7.2. 커뮤니티 활동을 한다.
    7.2. 로그(Log)를 잘 이용해서 동작을 체크하자.
        - 디버그(Debug)모드를 자주 이용하면 동작을 한눈에 확인하기 어렵다.
        - 기록(로그)을 세밀하게 남겨서 확인하는 습관을 가지자.
    7.3. Android Reference를 꼼꼼히 읽어두자.
        - 어느 개발서적보다 낫다.
        - 개발서적들은 대부분 저자가 자세히 모르는 내용은 얼버무리게 된다.

     



P.S. 안드로이드 개발용 rule.set 설정하기

프로젝트에서 하이브리드앱 형태로 해서 모바일웹페이지를 안드로이드의 웹뷰에서 보여주며 동작시키는 앱을 만들었다.

제조사마다 다양한 종류의 디바이스에서 테스트를 해봐야하는 안드로이드 개발은 앞으로도 고역이 될 것 같다.


얼마간 나를 괴롭히던 녀석이 있었다.

로그인을 할때 CookieManager를 이용해서 웹뷰의 쿠키 Sync를 맞춰두고 로그인상태를 유지하도록 만들었다.

이 싱크를 맞추는 작업이 지금까지도 곤혹스럽다. 


갤럭시S는 사용자가 많다. 그런데 가장 이상한 안드로이드폰이 갤럭시S다. 갤럭시S를 제외한 안드로이드폰들에서는

정상적으로 동작하는 앱이 꼭! 갤럭시S에서는 다르게 반응하는 것이다. 후아.

인터넷을 뒤져보다가 이 문제에 대한 해결책을 찾았다.


  
/**
 * Remove all session cookies, which are cookies without expiration date
 */
public void removeSessionCookie() {
    final Runnable clearCache = new Runnable() {
        public void run() {
            synchronized(CookieManager.this) {
                Collection> cookieList = mCookieMap.values();
                Iterator> listIter = cookieList.iterator();
                while (listIter.hasNext()) {
                    ArrayList list = listIter.next();
                    Iterator iter = list.iterator();
                    while (iter.hasNext()) {
                        Cookie cookie = iter.next();
                        if (cookie.expires == -1) {
                            iter.remove();
                        }
                    }
                }
                CookieSyncManager.getInstance().clearSessionCookies();
            }
        }
    };
    new Thread(clearCache).start();
}

위의 소스를 보면 마지막에 new Thread(clearCache).start()가 실행되는 것이 보인다. CookieManager.removeSessionCookie() 가 스레드로 실행되는 것을 확인할 수 있다.

갤럭시S가 다른폰들과 다른 반응을 보인 부분이 이 부분이다.


인터넷에 해결방법이 있을까?


하는 생각으로 인터넷을 뒤적거리다가 해결방법을 찾았다.

jinu's blog : Android webview cookie sync 문제 : http://jinu.info/blog/372

1년 전에 작성된 글인데, 글의 중간에 보면

try { Thread.sleep(500); } catch (Exception e) {}


위의 코드가 핵심이다. 500ms의 강제 대기시간을 주어서 cookieManager가 세션쿠키를 삭제할 수 있는 충분한 시간적인 여유를 부여한 후에 진행되도록 하는 것이다.


<< 위의 내용을 힌트삼아서 수정한 소스 >>

  
public void removeAllCookie() {
        Log.d(LOG_TAG, "webViewHelper removeAllCookie execute.");
        cookieManager.removeAllCookie();
        threadSleep();
        setDefaultCookies();
        CookieSyncManager.getInstance().sync();
    }

    public void removeSessionCookies() {
        Log.d(LOG_TAG, "webViewHelper removeSessionCookies execute.");
        cookieManager.removeSessionCookie();
        threadSleep();
        this.httpClient = null;
        setDefaultCookies();
        CookieSyncManager.getInstance().sync();
    }

    private void threadSleep() {
        try {
            Thread.sleep(500);
        } catch (Exception e) {
            Log.d(LOG_TAG, "thread Exception!");
        }
    }

처럼 처리했다.

ubuntu_logo.png

오늘(2011/03/23) 개발자분들과 번개로 만나 이런저런 이야기를 엿들은(?) 뒤, 집으로 돌아오는 길에 문득 떠올라 이렇게 첫 페이지를 시작한다.

우분투(Debian Linux 기반의 배포용 리눅스 운영체제, 무료)를 기반으로 해서 개발환경을 구축하고 사용하기가 편해진 요즘,

여기저기 흩어져 있는 내용들을 정리할 겸해서 정리를 해보려고 한다.

 

  1. Ubuntu 설치
  2. 한글 설정, 폰트 설정
  3. JDK 설정(Path 설정)
  4. eclipse, STS (IDE)설치
  5. Trac, Maven, Subversion 설치
  6. 안드로이드 개발환경 구축
  7. Python 개발환경 구축
  8. Qt 개발환경 구축

이 글은 스프링노트에서 작성되었습니다.

각 안드로이드 프로젝트는 AndroidManifest.xml 이라는 매니페스트 파일을 가지는데, 이는 해당하는 프로젝트 계측구조의 루트에 저장된다.

매니페스트는 애플리케이션을 구성하는 각각의 컴포넌트(액티비티, 서비스, 콘텐츠 공급자, 브로드캐스트 수신자)에 대한 노드를 포함하고 있으며, 인텐트 필터(Intent Filter)와 권한(Permission)을 사용해 이들이 다른 컴포넌트 및 애플리케이션과 어떻게 상호작용하는지를 결정한다. 또한, 애플리케이션 메타데이터(아이콘이나 테마 같은)를 지정하기 위한 속성을 비롯해, 보안 설정과 단위 테스트에 사용될 수 있는 추가적인 최상위 노드 역시 제공

매니태그는 프로젝트의 패키지 설정을 위한 package 속성을 갖는 manifest 루트 태그로 구성된다.

  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.android.helloworld"
          android:versionCode="1"
          android:versionName="1.0">
      [...매니페스트...]
    </manifest>

 

manifest 태그는 애플리케이션을 구성하는 애플리케이션 컴포넌트, 보안 설정, 테스트 클래스를 정의하는 노드를 가진다.

  • application   매니페스트는 오직 하나의 애플리케이션 노드만을 가질 수 있다. 애플리케이션 노드는 속성을 사용해 개발자의 애플리케이션을 위한 메타데이터(타이틀, 아이콘, 테마 등)을 지정한다. 또한 애플리케이션 노드는 애플리케이션 컴포넌트를 지정하는 데 사용되는 액티비티, 서비스, 콘텐츠 공급자, 브로드 캐스트 수신자 태그를 담는 컨테이너 역할을 한다.

    1. <application android:icon="@drawable/icon" android:label="@string/app_name">
      [...애플리케이션 노드...]
      </application>

 

  • activity   activity 태그는 애플리케이션에 의해 보여지는 모든 액티비티에 필요하며, android:name 속성으로 클래스 이름을 지정한다. 매니페스트에 정의되지 않은 액티비티를 시작하려 하면 런타임 예외가 던져질 것이다. 각 액티비티 노드는 그 액티비티를 띄울 인텐트를 지정하는 intent-filter 자식 태그를 지원한다.
  1. <activity android:name=".Helloworld"
                      android:label="@string/app_name">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
    </activity>

 

  • service   activity와 마찬가지로, 애플리케이션에서 사용되는 각 서비스 클래스에 대해 새로운 service 태그를 하나씩 생성한다. 서비스 태그 역시 늦은 런타임 바인딩(Late runtime binding)을 지원하기 위한 intent-filter 자식 태그를 지원한다.
  1. <service android:enabled="true" android:name=".MyService"></service>

 

  • provider   provider 태그는 애플리케이션이 가진 각각의 콘텐츠 공급자에 대해 사용된다. 콘텐츠 공급자는 애플리케이션 간의 데이터베이스 접근과 공유를 관리하기 위해 사용된다.
  1. <provider android:permission="com.android.MY_PERMISSION"
            android:name=".MyContentProvider"
            android:enabled="true"
            android:authorities="com.android.myapp.MyContentProvider">
    </provider>

 

  • receiver   receiver 태그를 추가하면 애플리케이션을 띄우지 않고서도 브로드캐스트 수신자를 등록할 수 있다. 브로드캐스트 수신자는 한번 등록되고 나면 애플리케이션에 의해 일치하는 인텐트가 방송될 때마다 실행되는 전역 이벤트 리스너(event listener)와 같다. 브로드캐스트 수신자를 매니페스트에 등록함으로써, 이 처리를 완전히 자립적으로 만들 수 있다.
  1. <receiver android:enabled="true"
            android:label="My Broadcast Receiver"
            android:name=".MyBroadcastReceiver">
    </receiver>

 

  • user-permission   보안 모델의 일부로서, uses-permission 태그는 애플리케이션이 올바르게 동작하는 데 필요하다고 생각되는 권한을 선언한다. 애플리케이션 설치 과정 중 사용자에게 제시되어 권한 부여 혹은 거절이 결정될 것이다. 권한은 많은 네이티브 안드로이드 서비스에 요구되며, 특히 비용이 수반되거나 보안에 관계된 것들(전화 걸기나 SMS 수신 또는 위치기반 서비스(LBS) 사용 같은)에는 필수적이다.
  1. <uses-permission android:name="android.permission.ACCESS_LOCATION">
    </uses-permission>

 

  • permission   어떤 애플리케이션 컴포넌트에 대한 접근을 제한할 수 있으면, 권한을 매니페스트에 정의할 필요가 있다. 이러한 권한 정의를 생성하는 데에는 permission 태그가 사용된다. 이렇게 권한을 정의하고 나면, 애플리케이션 컴포넌트는 adnroid:permission 속성을 추가해 그 권한을 요청할 수 있다. 다른 애플리케이션이 보호된 이들 컴포넌트를 사용할 수 있으려면, 먼저 자신의 매니페스트에 uses-permission 태그를 포함해야 할 것이다(그리고 그 권한을 부여 받아야 할 것이다).
    permission 태그 안에 허용할 권한의 접근수준(normal, dangerous, signature, signatureOrSystem)과 레이블 그리고 그 권한이 주어짐으로써 오는 위험성에 대한 설명을 담은 외부 리소스를 지정할 수 있다.
  1. <permission android:name="com.android.DETONATE_DEVICE"
            android:protectionLevel="dangerous"
            android:label="Self Destruct"
            android:description="@string/detonate_desciption">
    </permission>

 

  • instrumentation   계측(instrumentation) 클래스는 실행 시에 액티비티와 서비스를 테스트하기 위한 프레임워크를 제공한다. 이들 클래스는 애플리케이션과 그가 갖는 시스템 리소스와의 상호작용을 모니터하기 위한 고리를 제공한다. 애플리케이션을 위해 생성한 테스트 클래스 각각에 대해 새로운 노드 하나씩을 생성한다.
  1. <instrumentation android:label="My Test"
            android:name="MyTestClass"
            android:targetPackage="com.android.aPackage">
    </instrumentation>

 

manifest.png ADT(Android Develope Tools)의 새 프로젝트 마법사는 새로운 프로젝트를 만들 때 자동으로 새 매니페스트 파일을 생성한다. 애플리케이션의 각 컴포넌트를 배워나감에 따라 다시 이 매니페스트로 되돌아 올 것이다.

이 글은 스프링노트에서 작성되었습니다.

  • 액티비티(Activity)  
    애플리케이션의 프레젠테이션 계층이다. 모든 화면은 Activity 클래스의 확장이 될 것이다. 액티비티는 뷰를 사용해 정보를 보여주고 사용자 액션에 반응하는 그래픽 사용자 인터페이스를 형성한다. 데스크톱 개발의 입장에서 볼 때 액티비티는 폼과 같다.
  • 서비스(Services)  
    애플리케이션의 보이지 않는 일꾼이다. 서비스 컴포넌트는 화면에 보이지 않은 채 실행되어, 여러분의 데이터 소스와 화면에 보이는 액티비티들을 업데이트하고 알림(notifications)을 생성한다. 서비스는 애플리케이션이 가진 액티비티가 활성 상태가 아니거나 화면에 보이지 않을 경우에도 계속 돼야 할 필요가 있는 정규적인 처리를 수행하는 데 사용된다.
  • 콘텐츠 공급자(Content Providers)  
    공유할 수 있는 데이터 저장소다. 콘텐츠 공급자는 애플리케이션 데이터베이스를 관리하고 공유하는 데 사용된다. 콘텐츠 공급자는 애플리케이션 경계를 가로지르는 데이터 공유에 선호되는 방법이다. 이는 다른 애플리케이션의 접근을 허용하는 개발자만의 콘텐츠 공급자를 구성할 수 있으며, 또한 다른 애플리케이션이 노출한 콘텐츠 공급자를 사용해 그들의 저장된 데이터에 접근할 수 있음을 뜻한다. 안드로이드 장치는 연락처 정보 같은 유용한 데이터베이스를 노출하는 여러 네이티브 콘텐츠 공급자를 가지고 있다.
  • 인텐트(Intent)  
    간단한 메시지 전달 프레임워크이다. 개발자는 인텐트를 사용해 메시지를 시스템 전역이나 원하는 대상 액티비티 또는 서비스에 방송하고, 어떠한 동작을 수행시키고자 하는 여러분의 의도를 전달할 수 있다. 그러면 시스템은 해당 동작을 수행할 대상(들)을 적절히 결정할 것이다.
  • 브로드캐스트 수신자(Broadcast Receivers)  
    인텐트 브로드캐스트의 소비자다. 애플리케이션은 브로드캐스트 수신자를 생성해 등록함으로써, 특정 필터 조건과 일치하는 브로드캐스트 인텐트에 귀 기울일 수 있다. 브로드캐스트 수신자는 수신되는 인텐트에 반응해 자동으로 개발자의 애플리케이션을 시작시킬 것이며, 이들은 이벤트 중심 애플리케이션에 적합하도록 만들 것이다.
  • 알림(Notifications)  
    사용자 알림 프레임워크다. 알림은 사용자의 현재 액티비티가 가진 포커스를 빼앗거나 방해함 없이 사용자에게 신호할 수 있도록 해준다. 이는 서비스나 브로드캐스트 수신자에서 사용자의 주의를 끌기 위해 선호되는 기법이다. 예컨대, 장치는 텍스트 메시지를 수신하거나 전화가 걸려올 때 불빛을 깜박이거나, 소리를 내거나, 아이콘을 표시하거나, 다이얼로그 메시지를 보여줌으로써 사용자에게 알린다.

이 글은 스프링노트에서 작성되었습니다.

+ Recent posts