Android Studio를 OSX(내 경우에는 Yosemite 나 El Capitan 버젼) 에 설치하다 보면 발생하는 에러가 다음과 같다.



종종 발생하는데 해결하는 방법은 쉽다.

$ export STUDIO_JDK=/Library/Java/JavaVirtualMachines/jdk1.7.0_xx.jdk
$ open /Applications/Android\ Studio.app

위에서 xx 는 자신의 버젼에 맞게 쓰여져야 한다. 참고로 내꺼는 25 ("jdk1.7.0_25.jdk")이다. 안전하게 .bash_profile 에 STUDIO_JDK 값을 지정해주는 것이 좋다.


저는 습관처럼 gradle 을 command line 에서 사용합니다. 다만 최근 무지하게 느려진 느낌입니다. 자성의 움직임이 있었는지 최근 gradle 도 daemon 모드를 말하는 군요. 세팅은 무지하게 쉽습니다. 


touch ~/.gradle/gradle.properties && echo "org.gradle.daemon=true" >> ~/.gradle/gradle.properties

이렇게만 하면 비약적으로 빌드 속도가 올라간다는데 저는 사실 잘 모르겠습니다. -ㅅ-  Android Studio 도 빨라지는지는 테스트 해봐야 할 듯합니다. 


안드로이드 어플리케이션 개발시 strings.xml 에 html tag 를 삽입할려고 하다 보니 ADT안드로이드 스튜디오 와 호환성 문제가 발생하더군요.

1 현상

<string name="string_hello"><font color="#fffff">메모<![CDATA[<tt> </tt>]]> %1$s</font></string>

위와 같이 html tag 를 strings.xml 에서 사용할때 공백문자를 사용하기 위해서 CDATA 태그를 조금이라도 적게 사용할려고 공백 문자에만 사용할려고 하다가 발생했습니다.

2 원인

]]> 태그가 마지막에 오지 않으면 발생한다는 에러가 발생합니다. 혹은 리소스 머지(merge) 시에 에러가 발생한다던가 , 잘 쓰고 있던 컴퍼넌트 (component) 가 없다는 등 종잡을 수 없는 에러가 발생합니다.

3 해결

<string name="string_hello"><![CDATA[<font color="#fffff">메모 %1$s</font>]]></string>

위와 같이 변경해 주면 해결됩니다. 공백은 단순히 CDATA 안에서 space 한칸만 두면 됩니다.

parseSdkContent failed

Could not initialize class android.graphics.Typeface


정확히는 위와같이 발생합니다. 그래서 다른 프로젝트를 가져와서 막상 실행시킬려고 하면 에러가 발생하는데 OSX  에서는 $HOME/.android 폴더를 강제로 지워주고 다시 시작하니까 문제 없이 동작합니다. 



Android NDK (Native Development Kit) 을 이용해서 개발하고 있습니다. NativeActivity 를 이용하고 있습니다. 그런데 작지만 해결하기 어려운 버그가 있습니다. 

NativeActivity 는 Java 의 Activity 의 일종인데 JNI 를 이용한 Native C/C++ Entry Point 를 쓰레드 (Thread)를 이용해서 호출하는 부분을 잘 감싸서 NDK 를 이용해서 개발하고자 하는 사람들에게 편의를 제공할려는 목적으로 만들어 진것으로 보입니다. 특히나 게임 , 전화, 멀티미디어 용 어플리케이션을 개발하는 사람들은 필히 관심을 가져볼 만합니다. 

발생한 이슈는  제가 추천한 책에서 언급된 소스에 다른 모듈을 붙일려고 하는 순간에 발생했습니다. 참고로 만들어본 Android.mk 파일입니다. 



LOCAL_PATH := $(call my-dir)
TOP_ROOT_PATH := $(LOCAL_PATH)

include $(call all-subdir-makefiles) 
# 이 하위 Android.mk 에서 Shared Library 를 만들어 줍니다. 
# 그 라이브러리 이름을  codec 이라고 (예를 들어서) 해줍니다. 

include $(CLEAR_VARS)

LOCAL_PATH = $(TOP_ROOT_PATH)

LS_CPPP=$(subst $(1)/, ,$(wildcard $(1)/*.cpp ))

LOCAL_MODULE := game 
LOCAL_SRC_FILES := $(call LS_CPPP,$(LOCAL_PATH))

LOCAL_CFLAGS += -D GL_GLEXT_PROTOTYPES

LOCAL_LDLIBS := -landroid -llog -lEGL -lGLESv1_CM
LOCAL_STATIC_LIBRARIES := android_native_app_glue png
LOCAL_SHARED_LIBRARIES := codec                          
# 이 부분이 문제의 그 부분입니다. 

include $(BUILD_SHARED_LIBRARY)

$(call import-module, android/native_app_glue)
$(call import-module, libpng)


이게 대체 뭐지? 라고 생각하시는 분들은 제가 곧 'NDK 프로그래밍 따라하기' 포스트 한 두개를 올릴테니 그 때까지 이 부분을 보실 필요는 없습니다. 

위의 Android.mk 를 이용해서 컴파일을 하면 libgame.so 가 만들어 집니다. 책에서 나와 있는 그대로 만들어 집니다. 그러나 codec 이라는 (libcodec.so)를 이용해야 하는 필요가 생겨서 따로 만들어 줘서 프로젝트에 포함시켜 주면 실행이 안되고 에러가 발생합니다. 

잘 된 캡슐화의 문제점 중의 한가지가 난감한 에러가 발생하면 해결하기 어렵다는 점입니다. 구글링도 해보고 여러가지 독립적인 테스트를 해 본 결과 전혀 엉뚱한 작업을 진행중에 해결이 됐습니다. 100% 확신을 한 바는 아니지만 NativeActivity 가 결국 Java 클래스 이고 내부적으로는 결국 JNI 를 이용해서 Library 를 불러오는데, 정해진 방법으로만 호출하기 때문에 (위의 예제의 경우에는 libgame.so ) 다른 라이브러리를 호출을 못하기 때문에 발생하는 것 같습니다. 따라서 해결해 주기 위해서는 몇가지 수동으로 처리해 줘야 합니다. 

$ cd $PROJECT_ROOT
$ cd src/com/comjuck/game     (없으면 만들어 주셔야 합니다)
$ emacs NativeActivity

package com.comjuck.game;

import android.app.NativeActivity;
import android.os.Bundle;

public class GameActivity extends NativeActivity {

	static {
		System.loadLibrary("codec");
	}


  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
  }
  
}


GameActivity 를 만들어주고 NativeActivity 에서 상속을 받습니다. (물론 package 경로에 맞춰주는 것을 잊어주시면 안됩니다) , 그리고 위에서 표기한 대로 추가해 준 라이브러리를 직접 불러줍니다. 
그리고 AndroidManifest.xml 을 열어서 추가해 준 Activity 를 android.app.NativeActivity 대신 지정해 줍니다. 

$ cd $PROJECT_ROOT
$ emacs AndroidManifest.xml 
 

    <activity android:name="PhoneActivity"
                  android:label="@string/app_name">


이제는 문제 없이 앱이 실행되는군요. 

ps. 이걸 알아내기 위해서 4시간을 소모했습니다. ㅜ.ㅜ 


저는 컴퓨터 관련 서적 자체를 잘 추천 안하는 편입니다. 요즘 같이 급박하게 기술이 바뀌는 세상에서는 사실상 공식 페이지가 최고의 레퍼런스가 되는 것이 현실이다 보니, 주변에서 기술 관련 서적을 산다고 하면 적극적으로 말리는 편입니다.

그러나 이 책은 정말 감히 추천할 만 합니다. 사실 저는 원서(Android NDK , Beginner's Guide)로 봤는데, 저자의 소스코드만 보더라도 상당한 내공이 느껴집니다. C++ 이나 Object Oriented Programming 에 상당한 조예가 느껴집니다. 팀원이 한글판으로 보고 있는데도 상당히 괜찮다고 하니 번역도 괜찮게 되어 있는 편인가 봅니다. 

안드로이드에서 가장 어려운 축에 드는 NDK(Native Development Kit) 부분을 '따라하기' 식으로 쉽게 풀어서 설명했을 뿐 아니라, 따라하기의 예로 든 것이 바로 '게임' 입니다. 더구나 철저하게 Bottom-up 식으로 설명을 하고 있기 때문에 아니 이게 이런 게임이 되는거야? 하는 신기함도 느끼실 수가 있습니다.

더구나 C 의 함수로 돌아가는 형태를 객체화를 시키는 능력을 보자면 코드를 만들어내는 사람의 내공을 느낄 수가 있는데 그런면에서 이 저자는 가히 탁월한 능력을 보여줍니다.

단 책이 몇 개의 심각한 오타를 가지고 있습니다. (국내판은 확인도 안하고 그대로 번역한 것 같은 느낌까지 준다고 하는군요. ) 따라하기 소스는 필히 원작자의 돌아가는 소스코드를 가지고 공부하시길 추천합니다. 

 
저는 안드로이드를 Emacs 로 개발하고 있는 중인데요. 외부 jar 가 추가 될 때 자동으로 classpath 에 추가 하고 자동으로 import 기능을 활성화 시키는 방안을 찾는 중인데, 없더군요.. 

물론 Eclipse 를 사용하면서 Google AdMob SDK 같은 외부 jar를 사용하기는 쉽습니다. 외부 라이브러리로 추가해 주면 끝이기 때문입니다. 다만 CLI (Command Line Interface) 에서 Ant 를 이용해서 빌드를 할 때는 마구 마구 귀찮아집니다. 하지만 쉽게 하는 방법이 생겼더군요. 

$(ANDROID_PROJECT_ROOT) 밑에 /libs 라는 디렉토리를 만들고 그 안에다가 GoogleAdMobAdsSdk-6.0.1.jar android-support-v4.jar 두개의 파일을 복사해줍니다. 


$(ANDROID_PROJECT_ROOT) 밑의 ant.properties 파일을 열고 다음과 같이 추가해 줍니다. 

  jar.libs.dir=libs


이제 

$ ant clean && ant debug 



해 주시면 성공적으로 바인딩 되는 것을 확인하실 수 있습니다. 

다만 위와 같이 따로 libs 를 추가해 주면 JDE 환경에서 자동으로 classpath 뒤져서 Import 해주는 기능이 libs 에 추가된 jar 에 대해서는 동작하지 않습니다. 이럴 때를 위해서 따로 함수를 만들어 뒀습니다. (100% 제가 만든것입니다 쿨럭..) 



(defun android-mode-my-hook () 
  (progn
    (and (file-exists-p 
          (concat (android-root) "/libs"))
         (setq jde-global-classpath 
               (append jde-global-classpath 
                       (directory-files
                        (concat (android-root) "/libs")
                        t "jar"))))
    ))
(add-hook 'android-mode-hook 'android-mode-my-hook)


다음과 같이 만들어 주면 됩니다. 저는 java 설정만 따로 모아놓고 쓰지만 그렇지 않으신 분들은 .emacs 파일 구석에 적어두시면 될 것입니다. 물론 jdee 와 android-mode 설정 뒤에 적어주셔야 할 것입니다. jde-global-classpath 는 jdee 를 추가 해줘야 생기는 변수고 android-root 는 안드로이드 프로젝트의 루트를 찾아주는 편리한 함수인데 android-mode 를 추가해줘야만 쓸 수가 있습니다. 

점점 lisp 으로 코딩하는게 재밌어 지기 시작합니다. ㅎㅎ 
 
필요에 따라서 Eclipse 최신 버젼에 (Kepler) ADT 플러그인을 설치해서 사용중입니다. 이유는 간단합니다. 서버와 클라이언트를 동시에 개발할 일이 생겨서 그렇습니다. J2EE 와 ADT 를 따로 따로 설정해주는 방법도 있지만, 그 무겁고 귀찮은 Eclipse 를 두개나 깔아서 쓰라니요 절대 그럴 수는 없었습니다. 

최근 Eclipse 와 ADT 가 업그레이드 되면서 누락 된 부분이 있어서 수동으로 설치를 해줘야 한다고 합니다.

원문참조 : http://stackoverflow.com/questions/16608524/eclipse-giving-error-missing-r-java-file-after-recent-update?lq=1

원문 참조 이구요. "Android SDK Manager" 버튼를 클릭해서 창을 띄우고 

 
위 그림에서 체크된 항목을 설치해 주면 된다고 합니다.

 
제가 최근에 읽었던 프로그래머들의 특징에 관한 글중에서 공감이 갔던 구절이 하나 있습니다. 

"프로그래머는 UX (User eXperience)를 개발한다고 해도 자신이 좋아하는 환경은 CLI (Command Line Interface)다" 


 다시금 진행하기전에 다짐하듯이 말씀드리는 사항은 안드로이드 (Android) 개발하기에 최적의 환경은 Google 에서 제공하는 ADT (http://developer.android.com/intl/ko/sdk/index.html) 환경에서 개발하는 것입니다. 이 포스트는 ADT 에서 개발을 진행하더라도 자꾸 자꾸 눈이 CLI 환경에서 떠나지 않는 중독자(?!!)들을 위한 것입니다. 

 이 포스트는
Emacs Version 24로 업글후 Clojure 와 Common Lisp 개발 환경 갖추기 의 연장선상에 있으며 (Version 24 로 올라간 후 정말 많은 것이 바꼈습니다), Snow Leopard 에서 Emacs 를 Android 개발환경 IDE 로 세팅의 연장선상 이기도 합니다. 그 시절과는 정말 많은 것이 달라졌더군요. 


Android SDK 다운로드 
     
http://developer.android.com/intl/ko/sdk/index.html 에서 'USE AN EXISTING IDE' 라고 되어 있는 부분을 누르시면 SDK 만 받는 부분이 있습니다. 받아서 적당한 곳에 풀어주시면 됩니다. 저는 "~/work/android" 에 풀어줬습니다.
 
     
.profile 에 PATH 추가 

export ANDROID_SDK_HOME=/Users/<자신의 아이디>/work/android/sdk
export PATH=$ANDROID_SDK_HOME/platform-tools:$ANDROID_SDK_HOME/tools:$PATH

     
이 내용을 추가해 줍니다. 이제 어디서건 android 명령과 adb 명령을 사용할 수가 있게 됩니다. 
 
     
android-mode 설치해주기 

$ git clone git://github.com/remvee/android-mode.git


 로 적당한 곳에 받아줍니다. 제 경우에는 "~/.emacs.d/android-mode" 입니다. 그리고 "$ANDROID_SDK_HOME/tools/lib" 에 있는 android.el 을 "~/.emacs.d/android-mode" 에 복사해줍니다. 
 

.emacs 파일에 android-mode 관련 내용 추가 



(add-to-list 'load-path "~/.emacs.d/android-mode") 
(require 'android-mode)
(require 'android)
(setq android-mode-sdk-dir "~/work/android/sdk")


를 추가해줍니다. 각각의 디렉토리는 제 것을 기준으로 했으니 자신의 디렉토리로 바꾸어 주는 작업이 필요할 것입니다. 
 

JDEE (Java Development Environment for Emacs) 설치하기 

JDEE Project Page 에서 받을 수도 있지만 저는 편하게 미러에서 받는 것을 선택했습니다. 
     

$ cd ~/.emacs.d 
$ git clone git://github.com/emacsmirror/jdee.git


 라는 식으로 적당한 곳에 jdee 를 받아줍니다. 그리고 이것을 컴파일 해줘야 하는데 아마 그냥 안 될것입니다. 
 Ant-Contrib 이라는 것이 필요합니다. "여기" 에서 다운 받을 수 있습니다. ant-contrib-1.0b3-bin.tar.gz 를 다운받고 압축을 풀어서 (ant-contrib-1.0b3.jar 파일이 나옴) 위의 디렉토리인 "~/.emacs.d/jdee" 로 복사해줍니다.  

$ emacs ~/.emacs.d/jdee/build.xml 


로 간단한 조작을 해줍니다. 기존 부분을 아래와 같이 변경해 줍니다. (금방 찾을 수 있습니다 !!)

<!-- add in the contribs (add ant-contrib-VERSION.jar) to CLASSPATH -->
<taskdef resource="net/sf/antcontrib/antlib.xml">
  <classpath>
    <pathelement location="/Users/&lt;자신의 아이디&gt;/.emacs.d/jdee/ant-contrib-1.0b3.jar">
  </pathelement></classpath>
</taskdef>


$ cd ~/.emacs.d/jdee
$ ant build 

해 주면 모든것이 컴파일 됩니다. 
 

Elib-1.0 설치하기 

 예전에 링크로 걸어둔 곳에 가봤더니 이제 받는 곳을 찾기가 어려워 졌습니다. 아마 기본적으로 Emacs 에 포함된 것이 아닐까 생각도 해보지만 혹시 모르니 제 디렉토리에 있는 것을 올려둡니다. 

 
첨부파일을 다운 받으시고 
     

$ tar xvzf elib-1.0.tgz 


로 적당한 곳에 풀어주시면 됩니다. 참고로 저는 "~/.emacs.d/elib-1.0" 에 풀어줬습니다. 


JDEE 세팅하기 

 저는 보통 세팅을 나눠서 하는 것을 좋아합니다. 주력하고 있는 프로젝트에 따라서 .emacs 파일을 조금씩 조절하는 것을 즐겨하기 때문에 이번에도 그런식으로 했습니다. 

$ emacs ~/.emacs 

     
로 열어서 맨 아래쪽에 


(require 'cr-jdee)


를 추가해줍니다. 그리고 

$ emacs ~/.emacs.d/cr-jdee.el


로 열어서 다음과 같은 내용을 채워줍니다. 


;;;
;;; jdeee settings 
;;;


(add-to-list 'load-path "~/.emacs.d/elib-1.0")
(add-to-list 'load-path "~/.emacs.d/jdee/build/lisp")

(setq jde-help-remote-file-exists-function '("beanshell"))

(require 'jde)

;;
;; 저장할 때마다 자동으로 import 정리해주기 
;;
(defun java-my-hook ()
  (progn
    (define-key jde-mode-map [(control return)] 'jde-complete)
    (add-hook 'before-save-hook
              (lambda ()
                (jde-import-kill-extra-imports)
                (jde-import-all)
                (jde-import-organize))
              nil t)
    ))

(add-hook 'jde-mode-hook 'java-my-hook)


(custom-set-variables
 `(jde-global-classpath (quote 
    ("/Users/<자신의 아이디>/work/android/sdk/platforms/\
      <자신의 주력 타겟:예로 android-16>/android.jar" 
     "/Users/<자신의 아이디>/.emacs.d/jdee/build/classes"))))

(provide 'cr-jdee)



이렇게 저장해 주면 기본적인 세팅은 끝입니다. 중간에 java-my-hook 함수로 하는건 몇 가지가 있지만 그중에 제일 편리한 기능이 파일 저장할 때 알아서 import 문을 추가해 주는 기능입니다. Eclipse 의 Cmd + Shift + O 누르면 해주는 기능과 비슷합니다. 처음 실행할 때 beanshell 실행하느라 좀 느리긴 하지만 일일이 찾아주는 것보다 얼마나 편합니까? ㅎㅎ 
     

테스트 하기 

프로젝트 만들고 간단하게 빌드 + 테스트는 
예전 포스트 와 Command Line 에서 프로젝트 관리하기 를 참조하시면 됩니다. 이 부분은 추후에 조금 더 보강해서 정리하겠습니다. 


윈도에 테마 같은걸 까는것을 안 좋아하는 편인데요. 이 테마는 진짜 마음에 들더군요. 어디선가 우연히 본게 기억나서 한참을 뒤졌습니다. 

시원하게 라이트 세이버로 사과(?)를 베어 버리는 군요. 여러모로 마음에 드는 그림 아닌가요? ㅎㅎ 

테마는 위에 링크된 곳에서 받을 수 있습니다. 





+ Recent posts