요즘 Android NDK 를 이용해서 개발을 진행중인데, 화가 나는(?) 일이 발생해서 포스팅을 남기게 되었습니다. $(NDK_HOME)/docs/PREBUILTS.html 에 보면 

A prebuilt module does not build anything. However, a copy of your prebuilt shared library will be copied into $PROJECT/obj/local, and another will be copied and stripped into $PROJECT/libs/<abi>.

 
이런 문구가 있습니다. 하지만 시키는 대로 하니 복사는 커녕 어떠한 동작도 발생하지 않는 것을 발견했습니다. 미치는 지 알았습니다. 한 두시간을 구글링 했어도 어디에서도 명확히 답을 주는 부분이 없었습니다. 보통 이정도라면 방법은 하나 입니다. 직접 빌드 시스템을 까보는 수밖에 없지요.  

$(NDK_HOME)/build/core/prebuilt-static-library.mk 

위의 파일이 prebuilt-static-library 에 관한 부분입니다. 그 안을 보면 다음과 같은 문구가 있습니다. 

# Prebuilt static libraries don't need to be copied to TARGET_OUT
# to facilitate debugging, so use the prebuilt version directly
# at link time.


즉 요약을 하자면, 매뉴얼에서는 복사를 한다고 써 있지만, 실제로 동작하는 코어 모듈에서는 직접 링크를 하라는 식으로 쓰여져 있더군요. 

결론은 prebuilt-static-library 를 사용할려면 실제로 매뉴얼에 있는대로 동작을 하지 않습니다. 직접 라이브러리 링크를 걸어주시기를 추천합니다. 
 
필요에 따라서 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" 버튼를 클릭해서 창을 띄우고 

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

 
푸시 기능 구현을 Node.js 에서 하기에는 너무 쉬운 관계로.. 안드로이드 쪽부터 보기로 하겠습니다. 
안드로이드는 실 기계에서 작업하지 않는 한 에뮬레이터에서 푸시 기능을 테스트 해 보기 위해서는 Google API 를 지원해야 합니다.

Android SDK Manager (Windows 메뉴에 보면 있습니다. OSX 기준) 를 실행시키고 화면을 보면 


Android 4.2 (API 17) 에 'Google APIs' 가 설치 되어 있어야 합니다. 만약 설치 안되어 있다면 체크박스에 체크 하고 설치해주시면 됩니다. 

Google API 가 설치되어 있는 형태의 '가상 기계'를 구동하셔야 푸시 이벤트 처리가 가능합니다. 

Android Virtual Device Manager 를 실행시킵니다. (역시 Windows 메뉴에 있습니다) 
그리고 새로 '가상 기계'를 설정해 주는데 OS 버젼 골라주는 곳? 그곳에서 Google API 라고 쓰여져 있는 버젼을 골라주면 됩니다. 


자 제것의 화면입니다. 같은 4.2 버젼이지만 Google API 를 쓰느냐 안 쓰느냐의 차이만 존재합니다. 

그리고 다시 Android SDK Manager 를 실행시켜줍니다.

 
위에 보이는 라이브러리를 설치해줍니다. 자 그러고 나면 

$SDK/extras/google/gcm/ 밑에 보면 프로젝트들이 설치되어 있습니다. 그중에서 samples 밑의 gcm-demo-client 를 주목해야 합니다.  (본인의 경우에는 /Users/crazia/work/android/sdk/extras/google/gcm/samples/gcm-demo-client 에 설치되어 있습니다. )

Eclipse 가 이미 구동되어 있을 테니 (안 그러면 SDK 메니져랑 가상 기계 매니져를 실행시킬 수 없었겠지요?) 위에 지정한 프로젝트를 Import 해옵니다. 

자 이제 안드로이드 쪽에서 해야 할일의 90% 는 끝이 난 셈입니다. 이제 키가 두개 필요합니다. 편의상 Project Key (SEND ID) 와 API Key 라고 부르겠습니다. 각각 클라이언트와 서버쪽에서 필요한 키입니다. 

https://code.google.com/apis/console 에 접속하셔서 


아직 등록이 안되어 있다면 'Create Project' 를 누르시면 프로젝트가 생성됩니다. 그리고 나면 URL 이 자동으로 변경이 되는데. 

https://code.google.com/apis/console/#project:4815162342

여기서 보이는 저 굵은 글자가 바로 Project Key 입니다. (SEND ID) 아이템을 얻었습니다!!

왼쪽에 탭을 보면 여러가지 메뉴가 있는데 그중에 

"Services." 탭을 선택합니다. 
"Google Cloud Messaging" 을 ON 으로 토글링 합니다. (켭니다) 


이제 구글 클라우드 메시지 서비스를 이용하기로 결정이 됐습니다. 
자 다시 왼쪽 탭을 보면 그중에서 

"API Access" 탭을 선택합니다. 
아래쪽에 보면 "Create New Server Key" 라는 버튼이 있습니다. 
보내고 싶은 IP 리스트에 대한 리스트를 작성해 주고 싶으면 작성하고 마땅히 할게 없으면 "Create" 버튼을 눌러줍니다. 



이제 중간에 나오는 화면에서 "API Key" 부분에 나와 있는 키를 따로 떼서 저장합니다. (Server Key) 아이템을 얻었습니다!!

중간 점검을 하자면 

1. Google API 를 지원할 수 있게 Virtual Device 를 생성하는 준비를 마쳤습니다. 
2. Extra/gcm 샘플 소스를 받아서 Eclipse 에서 쓸 수 있게 Import 했습니다. 
3. Sender ID 와 Server Key 로 사용할 수 있는 Project Number 와 API Key 를 받았습니다. 

여기까지 완수가 되었다면 이제 클라이언트 (Android) 쪽 코딩을 마무리 지어 봅니다. Eclipse 의 프로젝트에 포함된 파일중에서 CommonUtilities.java 파일을 열어줍니다. 

    /**

     * Base URL of the Demo Server (such as http://my_host:8080/gcm-demo)

     */

    static final String SERVER_URL = "http://192.168.0.36:3000";
    // node.js 서버가 기다리고 있는 주소와 포트를 적어 주는 것입니다. 


    /**

     * Google API project id registered to use GCM.

     */

    static final String SENDER_ID = "4815162342";
    // 위에서 얻은 Project Number 를 입력해 줍니다.

이로서 클라이언트 부분은 끝이 났습니다. 이제야 제일 핵심인 Node.js 에서의 푸시 기능 구현에 들어가겠습니다.

$ cd $PROJECT_DIRECTORY
npm install node-gcm --save

-- save 옵션을 package.json 에 해당 사항을 기입하라는 뜻입니다.  

app.js 를 열어서 다음과 같이 추가 해 줍니다. 

var main = require('main');

app.post('/register', main.regist);
app.get('/send', main.send_push);


main.js 파일을 하나 만들어서 열고 

exports.regist = function (req, res) {

console.log (req.param('regId'));
        // 원래는 DB 에 저장하는 부분이 있어야 할 것입니다. 받아서 디비에 저장하기       

res.end(); 


exports.send_push = function(req, res) {

var message = new gcm.Message();

var sender = new gcm.Sender('API Key 를 입력하는 곳입니다. ');

var registrationIds = [];


// Optional

message.addData('key1','message1');

message.addData('key2','message2');

message.collapseKey = 'demo';

message.delayWhileIdle = true;

message.timeToLive = 3;


// At least one required

registrationIds.push('이곳은 register 함수에서 받은 regId 를 입력하는 부분입니다.');
        // 만약 제대로 구현 됐다면 디비에서 읽어서 가져오겠지요?  

        

/**

 * Parameters: message-literal, registrationIds-array, No. of retries, callback-function

 */

sender.send(message, registrationIds, 4, function (err, result) {

    console.log(result);

});

// sender.sendNoRetry(message, registrationIds-array, function (err, result) {

//     console.log(result);

// }); // retry 없이 보내는 부분입니다. 보통은 이것을 더 많이 애용할 것 같습니다. 

}




너무 쉽게 끝났지요? 이게 node.js 의 힘이라고 볼 수 있습니다. 자신의 안드로이드 프로젝트에 기능을 추가하고 싶으시다면 참조 사이트를 참조하시면 됩니다. 

참조  사이트 

https://github.com/ToothlessGear/node-gcm : node.js 에 gcm 모듈 구현 
http://developer.android.com/google/gcm/gs.html : 구글의  gcm 모듈 구현하는 설명 페이지 (완전 중요!!)


 
모바일 세상이 훌쩍하고 온지가 꽤 됐습니다. 안드로이드 폰이 아이폰에 비해서 왠만한 건 다 따라잡았다고는 하나 (스크롤 부드러움, 버츄얼 키보드 터치감 은 논외로 하지요) 사실 게임 부분은 따라가기가 힘든 부분입니다. 앞으로는 어떻게 될지 모르나 현재 나와 있는 게임들만 보자면 아이폰쪽이 월등히!! 많습니다. 

그런데 아이폰 게임들 수준을 보면 어떻습니까? 몇몇 대작을 빼고는 예전 슈퍼 패미콤 수준에서 머물러 있는 작품들이 대부분입니다.  

여기서 안드로이드 핸드폰에 플레이스테이션 에뮬레이터를 설치해서 돌아간다면 어떻겠습니까? 단숨에 초 대작 게임 3000 여개를 즐길 수 있게 되는 미니 게임기가 되는 것입니다. (공짜라는 것은 굳이 강조 안해도 되겠지요?)
더구나 예전 플레이스테이션 게임들은 적게는 수억에서 수십억을 쏟아부어서 만든 게임들 입니다. 


 
키패드가 눈에 거슬리긴 하지만  아주 훌륭하지 않습니까? 슈퍼로봇 대전 알파 외전 입니다. 어찌어찌 영문판을 구해서 재밌게 플레이 하고 있습니다. 

일단 에뮬레이터 입니다.

다운받기
 

그리고 다운받으시면서 아시겠지만 위의 파일을 제공하는 곳에서 에뮬레이터의 모든 것이 있습니다. (게임, 플스 바이오스 롬, 에뮬레이터) - 저작권 관련 때문에 더 이상은 언급하기 힘듭니다. 

위 파일을 받아서 압축을 풀면 나오는 *.apk 파일을 안드로이드 폰으로 옮기고 설치해 줍니다. 그리고 적당한 곳에 디렉토리를 한개 만들어 줍니다. (저는 download 밑에 만들어 줬습니다)

download/psx  



를 만들어 주고 그 밑으로

roms
game-roms


두개를 만들어 줬습니다.
roms 는 플스 바이오스 파일이 저장되는 곳입니다. 

BIOS PS1_scph1001.bin  



구글에서 위의 이름으로 검색해서 받으시거나 http://www.emuparadise.me/ 이 사이트를 뒤져보시면 나옵니다. 이 파일을 위에서 만들어 준 'roms' 에 저장합니다. 그리고 역시 어디선가 게임 롬을 받으셔서 'game-roms' 에 저장하시면 됩니다. 

그래서 처음 설치한 psx4droid 를 실행시키고

1. 'roms' 에 저장한 바이오스 롬 파일을 지정해 주고

2.  'game-roms' 에 저장된 게임 롬 파일을 지정해주면


바로 게임을 즐기실 수가 있습니다.  

수천종의 재밌는 게임을 즐기실 수가 있습니다.!! 

아!!
Galaxy
Galaxy II (아이스크림 샌드위치)
Galaxy Tab 8.9 LTE

세군데서 동작하는 것을 확인했습니다. 갤럭시2 같은 경우에는 진저브레드에서는 왜인지 모르지만 동작을 안하더군요.  
개발자로 살아 오면서 이거 저거 만지작 거리다 보니, 모바일 플랫폼쪽 개발을 자주 해보게 됐습니다. 윈도즈 모바일(Windows Mobile), 아이폰( iPhone)  , 안드로이드(Android) 로 이거 저거 만들어 봤습니다. 본의 아니게 자주 접하다 보니 이거 저거 장단점을 비교하게 되더군요.

나름 세개를 비교하는 오만을 저질를려고 하니 자신의 생각과 다르다고 하더라도 '이 사람은 이렇게 생각하는 구나' 하고 봐 주세요.

결론부터 이야기 하자면 개발자의 입장에서 가장 좋은 것은 안드로이드 라고 봅니다.

개인 개발자 측면에서 2가지만 이야기 하겠습니다. 추후에 상업화해서 돈을 얼마나 벌 수 있는 가에 대해서는 언급하기가 힘듭니다. 저 역시 그런 것으로 돈을 벌어본 적이 없어서요.

저는 그래서 개발자 측면에서 중요한 점을 돈과 개발 효율성 에 두고 있습니다.

첫째 돈에 관해서 입니다. 안드로이드는 개발하는 데 추가로 드는 비용이 전혀 없습니다.

Windows Mobile 개발할려면 돈이 듭니다. 다른건 모르겠지만 개발툴이 무지하게 비쌉니다. 모바일 개발 기능까지 포함한 Visual Studio 살려고 들면 몇백만원 이상으로 돈이 들 것입니다.

아이폰의 개발툴인 XCode 는 무료 입니다. 애플에 개발자 등록을 하면 바로 다운 받을 수 있습니다. 다만 개발을 하기 위한 OSX 가 깔려 있는 컴퓨터를 사야 합니다. 맥북 싼거부터 비싼 맥까지 가격은 천차 만별이지만, 맥 컴퓨터의 특성상 비쌉니다. 그리고 저 사양에서 개발은 쉽지가 않은 편이고요. 또한 맥북이 있다 하더라도 아이폰에 프로그램을 설치 하려면 '인증서'가 있어야 합니다. 개인 자격이니 1년에 10만원씩 인증서를 갱신하는 비용을 제공을 해야 아이폰에 자신이 개발한 프로그램을 설치 할 수가 있습니다.

"얘는 확실히 무료 입니다"



안드로이드는 사용하고 있던 피씨에 멀티 부팅으로 '우분투(Ubuntu)' 를 설치해주고, 이클립스(Eclipse) 를 설치하고, 안드로이드 SDK 를 설치해주면 개발 세팅 완료 입니다. 더구나 피씨 말고 전부 무료 입니다. 보통 피씨 없는 개발자는 없겠죠? 따라서 추가로 들어가는 돈은 전무 합니다. 개발을 잘 하기 위해서 새로 시스템을 갖추지 않는 경우에는 말이죠.

"개발 툴의 끝판 왕이라 불리는 이클립스"




둘째 개발 효율성 측면 입니다. 이것 역시 자바를 베이스로 하는 안드로이드의 압승입니다. 사실 돈 쓰는 것 이상으로 중요한 부분이기도 합니다.

윈도즈 모바일은 C/C++ 로 개발하게 되어 있습니다. (지금까지는 그래왔었습니다) C/C++ 은 개발 속도가 느리기 때문에 대부분의 개발자 들이 좋아하지 않는 언어로도 유명합니다.

아이폰은 C 에다가 Object Oriented 개념을 섞은 Object-C 라는 언어로 개발합니다. 엎어치나 메치나 제가 보기에는 C/C++ 계열입니다. 원래 인기 없는 언어였는데 아이폰 때문에 인기가 급 상승을 하고 있는 언어입니다.

안드로이드는 Java 로 개발을 합니다. 기존에 쓰고 있던 자바와는 좀 다르다고 하나 모바일 특성에 맞춘 것 외에는 일반적인 자바와 비슷합니다.

결국 개발할 때 세가지 플랫폼에서 가장 큰 차이는 포인터라고 볼 수가 있습니다.

저는 개발자로 살아온 인생 거의 모두를 C/C++ 개발하는 데 쏟았습니다. 저는 C/C++ 이 아주 몸에 익었기 때문에 포인터(Pointer)를 잘 이해하고 실전(?)에서도 자주 쓰는 편입니다. 그런데 이 포인터라는 것이 안 쓰다 보면 아주 귀찮아 지는 종류 입니다. 개발을 3년 넘게 쉬었다가 아이폰쪽 개발을 할 때 간만에 만나는 포인터가 저를 당황케 하더군요. 그런 의미에서 자바는 아주 훌륭하더군요. 가비지 컬렉션이 되는 것만으로도 이리 쉽게 프로그래밍을 할 수가 있구나. 라는 것을 느꼈습니다.

Java 나 Object-c 나 제 입장에서는 처음 배우는 언어인 데도 여타 다른 프로그래머 분들과 마찬가지로 자바쪽이 훨씬 쉽습니다.오죽하면 미국 버클리대에서 프로그래밍 기초 신청하는 학생들이 포인터 진도 나갈 때 60% 가 수강 철회를 하느냐는 말도 나오지 않겠습니까?

포인터를 완벽하게 이해하고 있으면 '전산형 인간' (Homo Computeres) 으로 기존의 사람들과 종이 다르게 분류되도 할 말은 없겠네요. 

간단하게 개발자 측면에서만 살펴 봤습니다. 하지만 오픈 마켓이 아이폰이 잘 되어 있지 않느냐는 말을 정말 많이 들었습니다. 그렇습니다 "왜? 개발을 하는가"도 중요하기 때문입니다. 결국 프로그램을 만들면 팔아서 돈을 벌어야 하는데 그런 제반 환경이 아이폰쪽이 잘 되어 있습니다. 하지만 굳이 팔려고 프로그래밍을 안하더라도 자신의 폰에 자신만의 프로그램을 만들어서 넣어보려는 용도로도 개발자들은 움직입니다. 그리고 그런 용도라면 정말 안드로이드를 추천합니다.

마음 편히 시작하고 아니다 싶으면 바로 접을 수도 있습니다.




+ Recent posts