好的,所以我需要介绍一些背景知识。首先,我将 jquery-mobile 与 PhoneGap 1.7 一起使用。 我编写了一个使用 ServerSocket 对象的非常简单的 Java 服务器。在 Android 手机上,我连接到服务器,然后服务器通过套接字发送数据。这部分正在运行。

我坚持的部分是我打算通过该套接字发送数据,这将需要在接收到数据时更新 jquery 移动 UI。


答案:西蒙帮了大忙,我在他的帮助下解决了这个问题,并关注了this tutorial

真正打动我的部分是在 PhoneGap 插件本身中生成线程。一旦我意识到这一点,一切都水到渠成。但是,对于任何感兴趣的人来说,这里是代码。请记住,我从教程中学到了很多东西。我还包含了为测试这些概念而创建的非常简单的 Java 服务器。我想也许这会在将来帮助某人。请记住,这基本上是一个概念证明。

我需要修改这个插件以满足我的实际需要:

Android Activity : 导入 org.apache.cordova.DroidGap;

import android.os.Bundle; 
 
public class ISSAndroidActivity extends DroidGap { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        super.loadUrl("file:///android_asset/www/index.html"); 
    } 
} 

PhoneGap 插件:

import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.InetSocketAddress; 
import java.net.Socket; 
import java.net.SocketAddress; 
import java.net.SocketException; 
 
import org.apache.cordova.api.*; 
import org.apache.cordova.api.PluginResult; 
import org.apache.cordova.api.PluginResult.Status; 
import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 
 
import android.util.Log; 
 
public class InvokeJavaScriptPlugin extends Plugin { 
    public static String PLUGIN_TAG = "InvokeJavaScriptPlugin"; 
    public static String PROCESS_DATA_ACTION = "processData"; 
    private String callBackId = ""; 
 
    @Override 
    public PluginResult execute(String action, JSONArray args, String callbackId) { 
        PluginResult pluginResult = null; 
        Log.d(PLUGIN_TAG, "Invoking Javascript w\\ NO_RESULT"); 
 
        if (action.equals(PROCESS_DATA_ACTION)) { 
            this.callBackId = callbackId; 
            startProcessingData(); 
            pluginResult = new PluginResult(Status.NO_RESULT); 
            pluginResult.setKeepCallback(true); 
        } else { 
            pluginResult = new PluginResult(Status.INVALID_ACTION); 
            Log.e(PLUGIN_TAG, "Invalid action : " + action); 
        } 
        return pluginResult; 
    } 
 
    /** 
     * Spawns a thread that connects to a server, and receives data from it 
     */ 
    private void startProcessingData() { 
        new Thread() { 
            @Override 
            public void run() { 
 
                // Socket Testing 
                ObjectOutputStream out; 
                ObjectInputStream in; 
                Socket requestSocket = new Socket(); 
                Object inboundObject; 
 
                SocketAddress ipAddr = new InetSocketAddress("192.168.1.2", 
                        2012); 
                try { 
                    requestSocket.connect(ipAddr); 
 
                    out = new ObjectOutputStream( 
                            requestSocket.getOutputStream()); 
                    out.flush(); 
                    in = new ObjectInputStream(requestSocket.getInputStream()); 
 
                    do { 
                        inboundObject = in.readObject(); // Data is received 
                                                         // here 
                        int processedData = ((Number) inboundObject).intValue(); 
                        onProcessDataReadSuccess(processedData); 
 
                    } while (requestSocket.isConnected()); 
 
                } catch (SocketException ex) { 
                    Log.d(PLUGIN_TAG, "Connection to Server lost"); 
                } catch (Exception ex) { 
                    ex.printStackTrace(); 
                } 
            } 
        }.start(); 
    } 
 
    /** 
     * Callback method for startProcessingData(). Sends the result up to 
     * javascript layer via Plugin.success()<br> 
     * This method is automatically called asynchronously when processing is 
     * finished. 
     *  
     * @param processedData 
     *            the result of data processing which will be passed back to 
     *            javascript. 
     */ 
    private void onProcessDataReadSuccess(int processedData) { 
        Log.d(PLUGIN_TAG, "Processing data: " + processedData); 
        PluginResult result; 
        try { 
            JSONObject resultJSON = new JSONObject(); 
            resultJSON.put("processedData", processedData); 
            result = new PluginResult(Status.OK, resultJSON); 
        } catch (JSONException jsonEx) { 
            Log.e(PLUGIN_TAG, "Got JSON Exception " + jsonEx.getMessage()); 
            jsonEx.printStackTrace(); 
            result = new PluginResult(Status.JSON_EXCEPTION); 
        } 
 
        result.setKeepCallback(true); 
        this.success(result, this.callBackId); 
    } 
} 

index.html:

<!DOCTYPE html> 
<html> 
<head> 
<title></title> 
<meta name="viewport" content="width=device-width, initial-scale=1" /> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<title>Insert title here</title> 
<link type="text/css" href="css/jquery.mobile-1.1.0.min.css" 
    rel="stylesheet" /> 
</head> 
<script type="text/javascript" charset="utf-8" 
    src="scripts/cordova-1.7.0.js"></script> 
<script type="text/javascript" src="scripts/jquery-1.7.2.min.js"></script> 
<script type="text/javascript" src="scripts/jquery.mobile-1.1.0.min.js"></script> 
<script type="text/javascript" src="scripts/InvokeJavaScript.js"></script> 
<script type="text/javascript" charset="utf-8"> 
    document.addEventListener('deviceready', function() { 
        window.plugins.InvokeJavaScript.processData(function(result) { 
            displayProcessedData(result) 
        }, function(error) { 
            console.log(error) 
        }); 
    }, true); 
 
    function displayProcessedData(result) { 
        document.getElementById("processedData").innerHTML = result.processedData; 
    } 
</script> 
 
<body> 
    <div data-role="page"> 
        <div data-role="header" data-position="fixed"> 
            <h1>Demo</h1> 
        </div> 
        <div data-role="content"> 
            Result: 
            <div id="processedData"></div> 
        </div> 
        <div data-role="footer" data-position="fixed"> 
            <div data-role="navbar"></div> 
        </div> 
    </div> 
</body> 
</html> 

服务器.java

import java.io.BufferedReader; 
import java.io.ObjectOutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 
 
public class ISSServer { 
 
    private static Socket androidSocket; 
    private static ServerSocket serverSocket; 
    static ObjectOutputStream out; 
    static BufferedReader in; 
 
    public static void main(String[] args) { 
        System.out.println("Listen Thread: Waiting for connection"); 
        int port_number = 2012; // The default port 
 
        try { 
            serverSocket = new ServerSocket(port_number); 
            androidSocket = serverSocket.accept(); 
 
            System.out.println("Connection established"); 
 
            out = new ObjectOutputStream(androidSocket.getOutputStream()); 
            out.flush(); 
            // in = new BufferedReader(new 
            // InputStreamReader(androidSocket.getInputStream())); 
 
            out.writeObject(1337); 
            out.flush(); 
            out.reset(); 
            System.out.println("1337 sent"); 
            Thread.sleep(2000); 
 
            out.writeObject(9999); 
            out.flush(); 
            out.reset(); 
            System.out.println("9999 sent"); 
            Thread.sleep(2000); 
 
            out.writeObject(1234); 
            out.flush(); 
            out.reset(); 
            System.out.println("1234 sent"); 
            Thread.sleep(2000); 
 
        } catch (Exception ex) { 
            ex.printStackTrace(); 
        } 
    } 
} 

请您参考如下方法:

你这样做是在折磨自己。如果您使用 PhoneGap 插件,您将能够保存初始 JavaScript 调用的回调 ID,然后发回您调用 result.setKeepCallback(true) 的 PluginResult 以及状态 PluginResult.Status.NO_RESULT。

然后,每当您在 Java 端获取和更新时,您都会创建一个新的 PluginResult。将状态设置为 OK,将数据设置为您想要发送的任何内容,当然在返回之前设置 KeepCallback(true)。然后调用 this.success(callbackId, result),你的 JS 端将得到持续更新。


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!