연재순서
작업환경
- Mac OS 10.7.4
- Flex SDK 4.6.0 for AIR3.3
- Flash Builder 4.6
소스 다운로드
[button url=’https://github.com/sewonist/ScreenWakeUp’ target=’_blank’ size=’large’]Sources in GitHub[/button]시작점 만들기
드디어 연재 마지막 시간입니다. 앞시간에 만든 파일들을 모두 모아 ane 를 만들어 보도록 하겠습니다. 사실 ane 빌드 자체는 한줄 명령어로 끝날 정도로 단순하지만 실제로 ane 를 만들려고 시도 할 때 많이 어려워하는 부분입니다. 그중 가장 큰이유는 GUI에 익숙해 있는 개발자가 커맨드라인을 이용해서 빌드 해야 하기 때문입니다. 그래서 많은 개발자들이 build.bat 이나 build.xml 을 이용해서 빌드를 하지만 커맨드라인을 수정해야 한다는 점은 변함이 없습니다. 그러므로 이번 기회에 adt를 이용한 빌드를 익혀 두는 것도 좋을 것 같습니다.
위의 디렉토리에 지금까지 만든 라이브러리와 SWC 를 모아 두었습니다. libScreenWakeUp.a 는 iOS용 라이브러리 에서 SecreenWakeUp.jar 는 Android용 라이브러리에서 마지막으로 ScreenWakeUp.swc는 연결 SWC 입니다. 그리고 나머지 2개의 xml 지금부터 차례대로 알아보겠습니다.
extension.xml
<extension xmlns="http://ns.adobe.com/air/extension/3.1"> <id>it.ane.ScreenWakeUp</id> <versionNumber>1.1</versionNumber> <platforms> <platform name="iPhone-ARM"> <applicationDeployment> <nativeLibrary>libScreenWakeUp.a</nativeLibrary> <initializer>ExtInitializer</initializer> <finalizer>ExtFinalizer</finalizer> </applicationDeployment> </platform> <platform name="Android-ARM"> <applicationDeployment> <nativeLibrary>ScreenWakeUp.jar</nativeLibrary> <initializer>it.ane.screenwakeup.ScreenWakeUpExtension</initializer> </applicationDeployment> </platform> </platforms> </extension>
xml 의 정확한 구조와 명세는 다음의 링크에서 확인 할 수 있습니다. Native extension descriptor files 여기서는 중요한 몇가지만 설명하겠습니다.
id
ANE의 고유 id 입니다. 이 아이디는 연결 SWC 가 context를 만들 때 사용하는 id와 동일합니다.
platform
각 플렛폼을 정의하는 노드 입니다. 플렛폼에 사용 할 수 있는 name 속성은 다음과 같습니다.
- Android-ARM for Android devices.
- default
- iPhone-ARM for iOS devices.
- iPhone-x86 for the iOS Simulator.
- MacOS-x86 for Mac OS X devices.
- QNX-ARM for Blackberry Tablet OS devices.
- Windows-x86 for Windows devices.
nativeLibrary
해당 플렛폼에서 사용한 라이브러리 파일명입니다.
initializer
미리 정의된 initializer 함수 또는 클래스명입니다.
AIR런타임은 위와 같이 extension.xml 에 정의된 값을 토대로 context 를 생성하는 것 입니다.
build.xml
<?xml version="1.0" encoding="UTF-8"?> <project name="Air Native Extension Build Scripts" default="package"> <property name="name" value="ScreenWakeUp"/> <property name="sdk.home" value="/Applications/Adobe Flash Builder 4.6/sdks/4.6.0_AIR3.3"/> <property name="bin.ext" value=""/> <target name="package" description="Create the extension package"> <exec executable="${sdk.home}/bin/adt${bin.ext}" failonerror="true" dir="./"> <arg value="-package"/> <arg value="-target"/> <arg value="ane"/> <arg value="${name}.ane"/> <arg value="./extension.xml"/> <arg line="-swc ${name}.swc"/> <arg line="-platform iPhone-ARM library.swf libScreenWakeUp.a"/> <arg line="-platform Android-ARM library.swf ScreenWakeUp.jar"/> </exec> </target> </project>
build.xml 은 빌드 자동화를 위한 ANT 설정 파일입니다. ANT 에 대해서는 위키에서 간단히 알아볼 수 있습니다. 예시로든 build.xml 은 단순히 ane 빌드만 하고 있으므로 딱히 ant 를 사용 할 필요 없어 보이지만 사실은 그렇지 않습니다. ane 개발은 네이티브 라이브러리, 연결 SWC 그리고 테스트 애플리케이션 까지 빌드가 되야 비로서 테스트가 가능합니다. 그런데 이런 일련의 과정을 일일이 빌드하려면 쓸데 없이 낭비되는 시간도 많을 뿐더러 불편하기 그지 없습니다. 그래서 보통 build.xml 에는 각 네이티브 라이브러리의 빌드, 연결 SWC의 빌드, 파일의 복사 및 압축 해제, ane 빌드 등이 모두 포함 되어 있습니다.
여기서 인자로 들어가는 -platform 은 extension.xml 에 정의된 platform 과 동일 해야 합니다. 그리고 시작점에서 보았던 폴더에 없던 파일이 보이는 바로 library.swf 입니다. 이는 ScreenWakeUp.swc 의 library.swf 입니다. ScreenWakeUp.swc 를 압축해제하고 같은 폴더에 library.swf 를 넣어두면 됩니다.
이제 모든 파일이 준비 되었다면 빌드를 해보겠습니다.
2초만에 빌드에 성공하였습니다. ㅎㅎㅎ 그리고 ScreenWakeUp.ane가 생성 된 것도 확인 할 수 있습니다. 이렇게 우리가 필요한 ane 제작이 완료 되었습니다.
테스트 하기
그럼 제작한 ane가 잘 작동하는지 테스트 앱을 만들어 보겠습니다.
프로젝트명을 입력하고 SDK는 AIR3.3 이상으로 합니다.
ScreenWakeUp.ane 는 iOS 와 Android 는 지원하니 두 플렛폼만 선택 합니다.
build 폴더에서 빌드된 ScreenWakeUp.ane 를 프로젝트 폴더에 복사합니다.
연결 SWC 를 이용하기 위해 Library path 를 설정합니다. ane는 ane파일안에 연결 SWC 를 포함하고 있으므로 따로 SWC 를 넣을 필요 없이 ane 파일 하나로 같이 사용 할 수 있습니다.
Native Extensions 탭에서 ANE 파일을 추가합니다. ane의 각종 정보를 확인 할 수 있습니다.
package { import com.bit101.components.Label; import com.bit101.components.PushButton; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.MouseEvent; import it.ane.ScreenWakeUp; public class ScreenWakeUpTester extends Sprite { private var _buttonOn:PushButton; private var _buttonOff:PushButton; private var _status:Label; private var _screenWakeUp:ScreenWakeUp; private var _isSupported:Boolean; public function ScreenWakeUpTester() { super(); stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; _buttonOn = new PushButton(this, 100, 20, "ScreenWakeUp ON", onClick); _buttonOff = new PushButton(this, 100, 50, "ScreenWakeUp OFF", onClick); _status = new Label(this, 100, 80, "status : OFF"); _screenWakeUp = new ScreenWakeUp; _isSupported = _screenWakeUp.isSupported; } protected function onClick(event:MouseEvent):void { if(event.currentTarget == _buttonOn){ if(_isSupported){ _screenWakeUp.lock(true); _status.text = "status : ON"; } } else if (event.currentTarget == _buttonOff) { if(_isSupported){ _screenWakeUp.lock(false); _status.text = "status : OFF"; } } } } }
위와 같인 간단히 테스트 코드를 작성 합니다.
_screenWakeUp.lock(true); //화면 잠금 설정 ... _screenWakeUp.lock(false); //화면 잠금 해제
ScreenWakeUp.ane 의 연결 SWC 인스턴스인 _screenWakeUp 을 이용하여 화면 잠금 해제를 할 수 있습니다. 마지막으로 아래와 같이 ane 파일을 패키지에 포함 시켜고 테스트 앱 프로젝트를 빌드합니다.
정리
총 5회에 걸쳐 ANE에 대해서 알아보고 iOS, Android 각 플렛폼용 라이브러리와 연결 SWC 를 만들어 보았습니다. 그리고 ANE를 빌드하여 테스트앱을 통해 정상 작동하는지도 살펴보았습니다. 사실 지금까지는 제가 미리 테스트한 샘플을 가지고 예제로 보여 드렸기 때문에 별 문제 없이 모든게 진행 되었습니다. 하지만 실제 개발에서는 지금 부터가 문제 입니다. 막상 ANE 개발을 해보면 여기까지 와서 테스트를 하면 안되는 경우가 상당히 많기 때문입니다. ANE의 태생적인 단점으로 여러 레이어층을 가진다는게 문제 입니다. 정확히 어느 부분에서 문제가 발생 했는데 파악하기가 어렵습니다. 디버그도 쉽지 않구요. 이를 해결 하기 위해서는 최대한 초기에 계획을 잘 세우고 중간중간 가능한 많은 테스트슈트를 만들어 테스트를 하면 진행 하여야 하겠습니다.
이번 연재에 사용된 모든 소스는 아래의 Github에 공유 되어 있으니 소스를 보시고 테스트해보시기 바랍니다. 긴글 끝까지 읽어 주셔서 대단히 감사합니다.^^
매우 좋은 정보 감사합니다.ㅎㅎ
제가 3달전에.. ane를 만들어볼려고 시도했었는데..
도움말이나 구글링 찾아서 해보았는데.. 역시나 안되더군요.. ㅠ
이유도 모르고 영어를 해석도 쉽지않고.. ㅠ
하지만 이제 좋은 정보를 얻어가니 잘 해볼수 있을꺼 같습니다.ㅎ
정말감사합니다.
도움이 되셨다니 작성자로서 정말 기쁘네요~ 막상 실제로 해보시면 크게 어렵지 않으니 꼭 성공하시리라 믿습니다.
swonist님 혹시
ScreenWakeUp.as에서 context.call(“Lock”, $flag); 를 호출하게 되면
Error #1009: Cannot access a property or method of a null object reference. 1009
이러한 에러가 표시 되는데 혹시 어떠한 이유로 에러가 나는지 아시는지요? 여러번 시도 끝에 해결방안은 찾지 못하여 이렇게 글을 씁니다. ㅜ.ㅜ
그리고 정말 좋은 정보 감사합니다.
우선 ScreenWakeUp.as 는 직접 호출해서 사용하시는 클래스가 아닙니다. 연재에도 설명했지만 ScreenWakeUp.as 는 플래시와 네이트 코드 사이의 브릿지 역활을 해주는 클래스 입니다. 즉 반드시 ANE내부에서 네이티브 코드와 함께 사용되어야 합니다. 위와 같은 에러가 발생했다면 가장 의심해 볼 부분은 역시 context 가 생성되지 않았을 가능성입니다. extension.xml 의 ID와 ScreenWakeUp.as의 ID 가 잘 매치 되는지 확인 해보시고 꼭 ANE로 빌드 후 테스트 코드에서 테스트 해보시기 바랍니다.
감사합니다. 드디어 해결이 되었어요~ㅎㅎ extension.xml 의 ID 값이 다르게 들어가 있어서 에러가 나는 것을 확인 하였습니다.
좋은 글 잘봤습니다.
내용이 좋네요. 정리도 잘 하셨고, 많은 도움되었습니다. 감사합니다.
도움이 되셨다니 영광입니다 ^^
안녕하세요! 좋은 강의 잘 봤습니다!
그런데.. 혹시 네이티브에서 어플쪽으로 메시지를 전달하는 강의도 부탁드려도 될까요?
어플 -> 네이티브 강의는 많은데 네이티브 -> 어플 쪽은 관련 내용이나 강의도 찾기가 힘드네요… 흑흑..
가능 하시다면 부탁드리겠습니다.
감사합니다. 조만간 시간이 허락하면 작성해보도록 할게요~^^
고맙습니다 잘봤습니다.!!