폰갭 플러그인 구분
폰갭 플러그인을 제작하려면 com.phonegap.api.Plugin 클래스를 상속받아야 하는데, 이 Plugin 클래스에 isSynch() 메소드가 있습니다. 기본적으로 false를 리턴합니다. 그러니까 이 메소드를 오버라이딩해서 true를 리턴하지 않는 이상 해당 플러그인은 비동기식으로 작동합니다.
비동기식 플러그인의 경우 플러그인 실행결과를 수신(콜백함수 호출)하기 위해 XMLHttpRequest를 이용하거나 또는 Polling 방식을 사용합니다.
동기식 플러그인 실행메커니즘
1. Javascript로 "window.plugins.플러그인명.액션명(...)"과 같이 플러그인 함수를 호출하게 되면, phonegap.js 내부적으로 PhoneGap.exec() 함수가 실행됩니다. PhoneGap.exec()에서는 prompt 함수를 실행하면서 플러그인 실행에 필요한 파라미터를 넘겨줍니다.
var r = prompt(xxx, "gap:xxx");
Javascript의 prompt() 함수가 호출되면 앱영역에서는 DroidGap$GapClient.onJsPrompt() 메소드가 실행됩니다. (아하, 폰갭은 Javascript -> Java 호출을 위해 prompt()를 활용하는군요.)
2. DroidGap$GapClient.onJsPrompt() 메소드에서는 prompt의 default value가 "gap:xxx" 형태의 문자열인 경우 PluginManager.exec(...) 메소드를 실행합니다. PluginManager.exec()에서는 아래와 같이 플러그인을 실행하고 그 결과를 JSON 스트링으로 리턴합니다.
// 동기식인 경우 current thread에서 플러그인을 실행
// (아래 코드는 원래 코드를 단순화한 것입니다)
PluginResult cr = plugin.execute(xxx);
3. DroidGap$GapClient는 PluginManager로부터 리턴받은 플러그인 실행결과 스트링을 prompt의 confirmation 응답으로 설정합니다.
jsPromptResult.confirm(플러그인 실행결과);
비동기 플러그인 실행메커니즘(XMLHttpRequest 적용시)
1. com.phonegap.CallbackServer는 java.net.ServerSocket을 이용하여 간단한 폰내부 로컬 웹서버를 띄웁니다. 이 웹서버는 웹영역의 XMLHttpRequest(XHR) 요청에 응답합니다.
2. phonegap.js의 PhoneGap.JSCallback 함수에서 로컬 웹서버와 ajax 통신하기 위한 연결을 맺습니다.
xmlhttp.open("GET", "http://127.0.0.1:xxx/xxx", true);
xmlhttp.send();
이 커넥션은 오랫동안 살아있는(long-lived) 연결이며, CallbackServer는 연결을 계속 유지하기 위해 10초간격으로 비어있는 응답을 계속해서 송신합니다(callback ping).
3. (동기식 플러그인과 동일하므로 설명생략)
4. PluginManager.exec()에서는 아래와 같이 비동기 플러그인의 경우 별도의 쓰레드를 만들어서 플러그인을 실행하고 그 결과를 CallbackServer에 적재합니다.
// 비동기식으로 정의된 경우 새로운 thread에서 플러그인을 실행
// (아래 코드는 원래 코드를 단순화한 것입니다)
5. CallbackServer는 새로운 플러그인 실행결과(javascript문자열)가 공급되면 그것을 기존에 연결된 XHR에 응답으로 씁니다.
response = "HTTP/1.1 200 OK\r\n\r\n";
output.writeBytes(response);
if (xmlhttp.status === 200) {
비동기 플러그인 실행메커니즘(Polling 적용시)
1. phonegap.js에서는 PhoneGap.JSCallbackPolling 함수를 주기적으로 실행합니다(기본 50ms 마다).
var msg = prompt("","gap_poll:");
2 ~ 3. (XHR 적용 비동기식 플러그인과 동일하므로 설명생략)
4. 폴링에 의해 호출된 DroidGap$GapClient.onJsPrompt() 메소드에서는 CallbackServer에 적재된 javascript문자열을 prompt의 confirmation 응답으로 설정합니다.
5. prompt 함수의 리턴값(var msg 변수)이 존재하면 그것을 evaluation하여 콜백 함수를 호출합니다.
XHR을 적용할 건가 Polling을 적용할 건가
PhoneGap.UsePolling = true;
그러나 폴링방식 적용시 폰갭은 비동기식 플러그인의 실행결과를 수신하기 위해 매우 짧은 주기로 App 영역과 통신하므로, 폰갭 기능이 필요하지 않은 웹페이지에서는 phonegap.js를 포함하지 않는 것이 좋습니다. 이 문제는 향후 어떻게든 개선될 것으로 보입니다.
ps. 위 내용은 폰갭 0.9.5 버전을 분석한 것입니다.
'Android' 카테고리의 다른 글
[안드로이드] PhoneGap 앱에서 신뢰할 수 없는 https 웹페이지 로딩하기 (0) | 2011.06.27 |
---|---|
[안드로이드] PhoneGap 앱에서 취소키 누르면 앱 종료하기 (0) | 2011.06.27 |
[안드로이드] 바이트 길이로 사용자 입력을 제한하는 InputFilter (11) | 2010.12.01 |
[안드로이드] 자잘한 팁 모음 (0) | 2010.12.01 |
[안드로이드] 메소드 프로파일링(profiling or tracing) (3) | 2010.11.05 |