1. Cordova Plugin이란
plugin은 Cordova Webview와 native platform간의 통신을 해 주는 Package이다. 이를통해서 Webview에서 할수 없는 일들을 native에서 실행을 할 수 있다.
Plugin은 하나의 자바스크립트 인터페이스로 이루어져 있으며 인터페이스 뒤에 여러 네이티브 코드를 숨길 수 있다
2. Plugin 설치
아래 두 커맨드중 하나로 설치 가능하다. npm에 cordova plugin이 설치되어있으면 아래것을 사용하자
cordova plugin add https://github.com/apache/cordova-plugin-device
cordova plugin add cordova-plugin-device
Plugin의 폴더에는 반드시 plugin.xml파일이 있어야 한다. 이 xml파일을 구성하는 방법은 다양하다. 구성하는 방법은 아래 페이지를 참고하자
아래는 간단한 버전으로 device라는 플러그인을 작성한 예시이다
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
id="cordova-plugin-device" version="0.2.3">
<name>Device</name>
<description>Cordova Device Plugin</description>
<license>Apache 2.0</license>
<keywords>cordova,device</keywords>
<js-module src="www/device.js" name="device">
<clobbers target="device" />
</js-module>
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="Device">
<param name="ios-package" value="CDVDevice"/>
</feature>
</config-file>
<header-file src="src/ios/CDVDevice.h" />
<source-file src="src/ios/CDVDevice.m" />
</platform>
</plugin>
- 가장 위에있는 plugin tag의 id 속성은 보통 cordova-plugin-{플러그인 이름} 형태로 작성한다
- js-module 태그는 common Javascript interface의 path를 입력한다
- platform 태그는 native platform을 명시한다. 위 케이스는 ios이다
- config-file 태그는 feature 태그를 감싼다. 그리고 이 feature태그는 config.xml 파일에 삽입된다. 이렇게 함으로써 platform은 추가적인 core library를 인식할 수 있다.
- header-file과 source-file 태그는 라이브러리의 컴포넌트 파일 경로를 명시한다
3. JavaScript Interface
자바스크립트 인터페이스는 cordova plugin의 가장 중요한 핵심이다. 개발자는 원하는대로 자바스크립트 인터페이스를 구현할 수 있지만, cordova.exec를 꼭 호출해서 불러야 한다.
사용법은 다음과 같다
cordova.exec(function(winParam) {},
function(error) {},
"service",
"action",
["firstArgument", "secondArgument", 42, false]);
- function(withParam)은 success callback이다. exec의 호출이 성공적으로 끝났을 경우 호출된다.
- function(error)는 error callback이다. exec가 성공적으로 마무리되지 못했을 때 호출된다.
- "service" 는 native쪽 코드를 부르기 위한 서비스 이름이다. 이것은 native class와 대응된다.
- "action"은 native쪽에서 하고싶은 작업이다. 이는 native class의 method에 대응된다.
- [argument] 는 native에 넘겨주고 싶은 arguments의 목록이다
아래는 위 사용 예시이다 예시이다
window.echo = function(str, callback) {
cordova.exec(callback, function(err) {
callback('Nothing to echo.');
}, "Echo", "echo", [str]);
};
window.echo("echome", function(echoValue) {
alert(echoValue == "echome"); // should alert true.
});
- 위 예제에서 cordova.exec의 세번째 파라미터를 보면 "Echo" 서비스를 호출한다. 앞서 배운것 처럼 이 서비스 네임은 native class 이름과 대응된다.
- 그다음 네번째 파라미터 "echo"는 action 즉 클래스의 메소드를 의미한다
- 마지막 [str]은 넘겨주는 arguments이다
4. Native Interface(Android)
본 내용은 앞의 echo 플러그인 예제에서 이어지는 내용임.
Android Plugin은 네이티브 브릿지를 통한 웹뷰로부터 생성되는 Cordova-Android를 베이스로 한다.
안드로이드 네이티브 인터페이스는 최소 하나의 자바클래스로 이루어져 있다. 이 때 CordovaPlugin 클래스를 상속받는다. 그리고 excute 메소드를 오버라이딩 한다.
Plugin Class Mapping
이제 본격적으로 살펴보자. 먼저 javascript 클래스와 native class를 Mapping 시켜주는 작업을 해 주어야 한다. 당신의 플러그인이 java 파일이든 jar파일이든 먼저 Cordova-Android Application의 res/xml/config.xml을 먼저 작성해주어야 된다
<feature name="<service_name>">
<param name="android-package" value="<full_name_including_namespace>" />
</feature>
- 위에서 service_name은 앞서 배운 exec의 service name과 매칭된다.
- value 는 자바 클래스의 네임스페이스 식별자이다. 즉 com.android.main 뭐 이런식으로 적어주면 된다.
이에따라 플러그인이 컴파일은 성공적으로 되지만 Cordova에서 동작하지 않을 수 있따. 잘 적어주자
Plugin Initialization and Lifetime
플러그인은 config.xml에서 onload가 true가 아니면, 호출되기 전 까지 인스턴스화 되지 않는다.
반대로 말하면 onload=true이면 호출되기 전에 이미 인스턴스화 되어있다
<feature name="Echo">
<param name="android-package" value="<full_name_including_namespace>" />
<param name="onload" value="true" />
</feature>
플러그인은 반드시 initialize 메소드를 사용해야 된다. (원문에는 use라고 나와있는데 오버라이드 반드시 하라는건지 마는건지..)
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
// your init code here
}
플러그인은 또한 안드로이드 라이프사이클 이벤트, 예를들어 onResume이나 onDestroy 같은 메소드들도 다룰 수 있다.
플러그인은 수행시간이 긴 작업들, 예를들어 미디어플레이 같은 작업들을 하면 반드시 onReset() 메소드를 implement 해 주어야 한다. 이 메소드는 WebView가 새로운 페이지 혹은 페이지 리프레쉬를 할 떄 마다 호출된다.
자바 플러그인 작성하기
자바스크립트가 네이티브쪽의 플러그인을 호출하면 config.xml에서 매칭되는 자바 플러그인을 찾아서 메소드가 호출된다.
자바 플러그인의 형태는 다음과 같이 생겼다
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if ("beep".equals(action)) {
this.beep(args.getLong(0));
callbackContext.success();
return true;
}
return false; // Returning false results in a "MethodNotFound" error.
}
Threading
플러그인의 자바스크립트는 메인스레드가 아닌 WebCore 스레드에서 동작한다. 그러므로 안드로이드 네이티뷰 UI를 만질 일이 있으면 반드시 mainThread에서 돌려주도록 하자. 아래는 runOnUiThread를 이용하여 메인스레드에서 작업하는 예시이다
@Override
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
if ("beep".equals(action)) {
final long duration = args.getLong(0);
cordova.getActivity().runOnUiThread(new Runnable() {
public void run() {
...
callbackContext.success(); // Thread-safe.
}
});
return true;
}
return false;
}
만약 당신이 UI 작업이 필요 없다 해도 WebCore 스레드를 blocking 하는것은 좋지 못한 방법이다. 코르도바에서는 이를 해결하기 위해 ExecutorService 라는것을 제공하고 이는 cordova.getThreadPool()을 이용하여 얻을 수 있다
@Override
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
if ("beep".equals(action)) {
final long duration = args.getLong(0);
cordova.getThreadPool().execute(new Runnable() {
public void run() {
...
callbackContext.success(); // Thread-safe.
}
});
return true;
}
return false;
}
'Cordova' 카테고리의 다른 글
Cordova에 대한 소개 (0) | 2023.01.09 |
---|
댓글