2013-03-21 44 views
5

Tôi đã xây dựng một Plugin rất đơn giản PhoneGap để bắt đầu thử nghiệm cách tôi sẽ xây dựng một số hành động gốc trên Android.Nhận giá trị trả về từ PhoneGap Plugin

JavaScript:

function callNativePlugin() { 
      cordova.exec(nativePluginResultHandler, nativePluginErrorHandler, "Database", "saveAdvertencia", [ 1, "TesteAdv" ]); 
     } 

    function nativePluginResultHandler(result) { 
     alert("SUCCESS: \r\n" + result); 
    } 

    function nativePluginErrorHandler(error) { 
     alert("ERROR: \r\n" + error); 
    } 

Java:

@Override 
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { 
    if (action.equals("saveAdvertencia")) { 
     advertenciaDS = new AdvertenciaDS(cordova.getActivity()); 
     callbackContext.sendPluginResult(new PluginResult(Status.OK, new JSONArray("test"))); 
     return true; 
    } 
    return false; 
} 

Những gì tôi cần là một cách để lấy kết quả từ hành động trong cùng một phương pháp. Nó rất phức tạp để luôn luôn đối phó với 3 phương pháp (1 để thực hiện hành động. 1 để xác định những gì sẽ là hành động thành công. 1 để xác định những gì sẽ là hành động lỗi.) Khi bạn không thực sự kiểm soát khi chúng được gọi, kể từ khi PhoneGap gọi cho họ sau khi hoàn thành hành động.

Nếu tôi cần phải lấy một số dữ liệu từ cơ sở dữ liệu Native Android:

  1. Gọi trong JavaScript là "cordova.exec".
  2. PhoneGap sẽ gọi plugin của bạn.
  3. Plugin của bạn sẽ trả lại 2 điều: Boolean cho PhoneGap xác định mọi thứ hoạt động như mong đợi hay không. Dữ liệu sẽ được chuyển đến các phương thức thành công.
  4. Đây là phần khó khăn đối với tôi. Nếu thành công hay không, bạn phải tạo 2 phương thức mà bạn không có quyền kiểm soát khi nào chúng sẽ được gọi, bởi vì PhoneGap sẽ quyết định điều đó. Làm cách nào để thay đổi điều này?
+0

@mafutrct Cảm ơn bạn đã sửa chữa định dạng văn bản! – MBarni

+0

Tất cả tín dụng đều được chuyển đến @Real, tôi vừa sửa một chi tiết nhỏ – mafu

Trả lời

5

tôi sử dụng mô hình này để chỉ có một callback cho các chức năng được cung cấp bởi các plugin:

function callNativePlugin(callback) { 
    cordova.exec(function(result) { 
     callback(null, result); 
    }, function(result) { 
     callback("myerror"); 
    }, "Database", "saveAdvertencia", [ 1, "TesteAdv" ]) 
}; 

Bằng cách này bạn sẽ có được callbacks phong cách Node.js trong đó số đầu tiên là lỗi và thứ hai là kết quả:

//define the callback function 
var callbackFunction = function(err, result) { 
    if (err) { 
     console.log("there was an error"); 
    } else { 
     console.log("success", result); 
    } 
}; 

//call the plugin 
callNativePlugin(callbackFunction); 

Bạn không thể tránh có hai cuộc gọi lại trong plugin, vì điều này được API cordova ủy quyền, nhưng bạn không phải tiết lộ điều đó với người dùng plugin của mình.

+0

Ý bạn là callNativePlugin? –

+0

Xin lỗi ... Tôi nhớ đã hiểu mã. Đã có nó làm việc ngay bây giờ. – MBarni

+0

Điều này có sai không? (phiên bản mới) http://pastebin.com/MTAH3MZN – MBarni

0

Trong JavaScript, tôi đã có thể lấy giá trị Plugin PhoneGap chỉ với một phương pháp đệ quy dễ dàng kiểm soát:

function callNativePlugin(result, error, service, action, json) { 
    if (result != null) { 
     //alert("SUCCESS: \r\n" + result); 
     return result; 
    } else if (error != null) { 
     //alert("ERROR: \r\n" + error); 
     return error; 
    } 
    return cordova.exec(function(result) {callNativePlugin(result, null, null, null);}, function(error) {callNativePlugin(null, error, null, null);}, service, action, json); 
} 
+0

Giá trị của điều này trên một bộ 3 chức năng mà vẫn không hoạt động là gì? Về cơ bản, bạn có một hàm hoạt động theo ba cách, và vẫn không hoạt động vì bạn không thể trả về một giá trị đồng bộ từ một cuộc gọi không đồng bộ như cordova.exec() (hoặc ít nhất không đơn giản và bạn không nên). Tức là, việc trả về từ hàm gọi lại không ảnh hưởng đến giá trị trả về của cordova.exec, và có thể xảy ra sau khi cordova.exec trả về. Tốt hơn là chỉ sử dụng nó không đồng bộ như được thiết kế: gọi lại hàm (giá trị) {console.log (giá trị); } cordova.exec (gọi lại, gọi lại, "Foo", "bar", []); –

+0

Tính năng này đang hoạt động và đang được sử dụng trên ứng dụng của tôi. Tại sao giảm hạng một aswer đang hoạt động? Làm cho câu trả lời của riêng bạn và nếu nó là thực sự tốt hơn và cũng giải thích, tôi sẽ bỏ phiếu nó như là một trong những chính xác. – MBarni

+0

Khi tôi nói nó không hoạt động, tôi có nghĩa là nó không trả lại kết quả hoặc lỗi, mặc dù nó sẽ gọi hàm gốc. Nó chỉ là một phiên bản phức tạp hơn của cái bạn có trong câu hỏi. Tôi cũng sẽ đề nghị một câu trả lời khác. –

2

Nếu bạn đang yêu cầu một cách để biến cordova.exec() từ một cuộc gọi không đồng bộ thành một cuộc gọi đồng bộ trả về một giá trị, câu trả lời ngắn gọn là bạn không thể. (Câu trả lời dài là bạn có thể giả mạo nó bằng cách sử dụng một vòng lặp hoặc thời gian chờ nhưng bạn không nên.)

Như Vlad giải thích, bạn có thể tạo giao diện riêng của bạn vì vậy bạn chỉ có một chức năng để gọi, nhưng tôi sử dụng một cái gì đó giống như phiên bản đơn giản này (trong http://htmlpresenter.com/api.html):

var Database = { 
    saveAdvertencia: function(args, callback) { 
    cordova.exec(callback, 
     function(error) { console.log("Error calling Database.saveAdvertencia: " + error); }, 
     "Database", "saveAdvertencia", args) 
    } 
} 

Sau đó gọi nó như thế này cung cấp gọi lại inline nếu bạn cần kết quả:

Database.Advertencia([1, "TesteAdv"], function(result) { alert(result); }); 

Tất nhiên nếu (như có vẻ là trường hợp), bạn không cần phải kết quả ở tất cả, bạn có thể chỉ cần sử dụng phiên bản này:

function saveAdvertencia() { 
    log = function(message) { console.log(message) }; 
    cordova.exec(log, log, "Database", "saveAdvertencia", arguments); 
} 

saveAdvertencia(1, "TesteAdv"); 

(Sửa :) Ngoài ra, thách thức này có thể liên quan đến điều này, câu hỏi tốt hơn:

Các vấn đề liên quan