5

わかりましたので、少し背景を説明する必要があります。まず、PhoneGap 1.7 で jquery-mobile を使用しています。ServerSocket オブジェクトを使用する非常に単純な Java サーバーをコーディングしました。Android フォンでサーバーに接続すると、サーバーはソケット経由でデータを送信します。この部分は機能しています。

私が立ち往生している部分は、データの受信時にjqueryモバイルUIを更新する必要があるソケットを介してデータを送信するつもりであることです。


回答: サイモンは大きな助けになりました。私は彼の助けとこのチュートリアルに従って理解しました。

私を本当に驚かせたのは、PhoneGap プラグイン自体でスレッドを生成したことです。それに気づいたら、すべてがうまくいきました。ただし、ここに興味がある人はコードです。覚えておいてください、私はチュートリアルから多くのことを学びました。これらの概念をテストするために作成した非常に単純な Java サーバーも含めました。これは将来誰かを助けるかもしれないと思いました。これは基本的に概念実証であることを覚えておいてください。

実際のニーズに合わせてこのプラグインを改良する必要があります。

Android アクティビティ: import 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();
        }
    }
}
4

1 に答える 1

7

あなたはこの道を自分自身に苦しめています。PhoneGap プラグインを使用すると、最初の JavaScript 呼び出しのコールバック ID を保存してから、result.setKeepCallback(true) を呼び出す PluginResult を送り返すことができ、ステータスが PluginResult.Status.NO_RESULT になります。

次に、Java 側で取得および更新するたびに、新しい PluginResult を作成します。ステータスを OK に設定し、データを送信したいものに設定し、もちろんそれを返す前に setKeepCallback(true) に設定します。次に this.success(callbackId, result) を呼び出すと、JS 側で継続的な更新が行われます。

于 2012-05-27T20:26:30.193 に答える