2014년 1월 22일 수요일

How to do Async at Android Phonegap custom plug-in.

Phonegap에서 Javascript와 plug-in 사이는 비동기로 호출된다는 것은 모두 아는 사실이다.
그런데 plug-in에서 다른 Activity을 비동기로 호출하는동안 Javascript에 return되는 Result을 대기 시키고 다른 Activity의 작업이 완료된 이후에 return하는 방법을 알아보자.

Flow는 다음과 같다.
  1. Javascript에서 custom-plugin의 “getAttachFile” 명령어을 호출한다.
  2. custom-plugin의 “getAttachFile” 명령어를 처리하는 부분에서 일시적으로 javascript로 리턴 되는 “PluginResult”을 대기 시켜 놓는다.
  3. custom-plugin은 “getAttachFile” 명령을 수행하는 Activity을 “startActivityForResult”로 호출한다. 또한 custom-plugin내에는 “onActivityResult”도 구현한다.
  4. “onActivityResult”에서 ‘2번’에서 대기시켰던 PluginResult에 Javascript에 전달할 데이터를 기록한 후에 send 한다.

위의 Flow을 Code로 보면

JavaScript 부분
cordova.exec(
function(result) {
console.log("Result: "+JSON.stringify(result));
var base64Data = result.base64Data;
var name = result.name;
var size = result.size;
$('#base64Data').html(base64Data);
$('#name').html(name);
$('#size').html(size);
},
function(e) {
console.log("Error: "+e);
}, "DEVPlugIn", "getAttachFile", [jsonString]
);

Custom Plug-in
public class TestPlugIn extends CordovaPlugin {

public static final int FILE_ACTIVITY = 0;
public static JSONObject accessParams = new JSONObject();
public static AttachFileVO attachFile = null;

private CallbackContext callbackContext;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent){
switch(requestCode){
case TestPlugIn.FILE_ACTIVITY:
if(resultCode == Activity.RESULT_OK){
if(attachFile != null) {
String base64Data = attachFile.getBase64Data();
String name = attachFile.getName();
long size = attachFile.getSize();
JSONObject dataParams = new JSONObject();
try {
dataParams.put("base64Data", base64Data);
dataParams.put("name",name);
dataParams.put("size",size);
} catch (JSONException e) {
}
attachFile = null;
PluginResult result =
                                                                  new PluginResult(PluginResult.Status.OK, dataParams);
                                   result.setKeepCallback(false);
callbackContext.sendPluginResult(result);
}
}
}
}

@Override
public boolean execute(String action, JSONArray args,
CallbackContext callbackID) throws JSONException {
if (action.equals("getAttachFile")) {
Intent intent = new Intent();
intent.setClass(cordova.getActivity(),FileExplorer.class);
cordova.startActivityForResult((CordovaPlugin) this, intent, FILE_ACTIVITY);
this.callbackContext = callbackID;
PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
result.setKeepCallback(true);
this.callbackContext.sendPluginResult(result);
return true;
}
return false;
}
}

위 Code는 Phonegap 2.x 버전에서 테스트 되었습니다. 지금은 3.x 버전인데 아직 안 써봤기 때문에 테스트 하지 못했습니다.

Which Mobile App Development Option is Better?

Different alternatives to native code development have their own advantages and philosophy behind. No one tool or approach can be clearly ma...