카테고리 없음

PhoneGap의 통신 방식 분석

삼스 2011. 10. 26. 19:05

웹페이지와 네이티브가 통신하기 위해 안드로이드, iOS, WindowPhone 7, ... 등등에 공통적으로 적용가능한 방법을 PhoneGap이 보여주고 있다.
안드로이드의 addJavaScriptInterface(?)는 타 플랫폼에서는 적용불가이므로 폰갭은 어떻게 다양한 플랫폼에 적용가능하도록 하였는지 확인하여 보았다.

BONDI나 거기에서 더 확장된 HTML5의 DAP에 있어서 다음의 필수요소가 있는데
 - 웹페이지에서 네이티브를 호출하여 그결과를 리턴받을 수 있어야 하고
 - 동기 및 비동기 호출이 가능해야 한다.


폰갭은 javascript의 prompt함수를 이용해서 네이티브와 연계하여 그 결과값을 받도록 되어 있다.

아래는 폰갭의 네이티브로의 호출및 반환을 담당하는 함수코드이다.

 PhoneGap.exec = function(success, fail, service, action, args) {
   try {
        var callbackId = service + PhoneGap.callbackId++;
        if (success || fail) {
            PhoneGap.callbacks[callbackId] = {success:success, fail:fail};
        }
        var r = prompt(PhoneGap.stringify(args), "gap:"+PhoneGap.stringify([service, action, callbackId, true]));
        // If a result was returned
        if (r.length > 0) {
            eval("var v="+r+";");
            // If status is OK, then return value back to caller
            if (v.status === PhoneGap.callbackStatus.OK) {
                // If there is a success callback, then call it now with
                // returned value
                if (success) {
                    try {
                        success(v.message);
                    } catch (e) {
                        console.log("Error in success callback: " + callbackId  + " = " + e);
                    }
                    // Clear callback if not expecting any more results
                    if (!v.keepCallback) {
                        delete PhoneGap.callbacks[callbackId];
                    }
                }
                return v.message;
            }
            // If no result
            else if (v.status === PhoneGap.callbackStatus.NO_RESULT) {
                // Clear callback if not expecting any more results
                if (!v.keepCallback) {
                    delete PhoneGap.callbacks[callbackId];
                }
            }
            // If error, then display error
            else {
                console.log("Error: Status="+v.status+" Message="+v.message);
                // If there is a fail callback, then call it now with returned value
                if (fail) {
                    try {
                        fail(v.message);
                    }
                    catch (e1) {
                        console.log("Error in error callback: "+callbackId+" = "+e1);
                    }
                    // Clear callback if not expecting any more results
                    if (!v.keepCallback) {
                        delete PhoneGap.callbacks[callbackId];
                    }
                }
                return null;
            }
        }
    } catch (e2) {
        console.log("Error: "+e2);
    }
}; 


prompt(PhoneGap.stringify(args), "gap:"+PhoneGap.stringify([service, action, callbackId, true])) 함수 호출부분이 네이티브와 연계되는 부분이다. 네이티브는 GapClient의 onJsPrompt()코드가 연계되고 여기서 처리되고 그 결과를 JSON string으로 리턴한다.

이게 가능한 이유는 
WebChromeClient가 javascript prompt함수가 호출될때 onJsPrompt()를 호출하여 override할수 있도록 지원하기 때문이다. 리턴은 json으로 넘겨받게 되어 있다.

다음 포스트에는 비동기 호출에 대해서 알아보겠다.