草庐IT

java - Android PhoneGap 1.7 调用 javascript 函数

coder 2025-03-18 原文

好的,所以我需要介绍一些背景知识。首先,我将 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 端将得到持续更新。

关于java - Android PhoneGap 1.7 调用 javascript 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10768934/

有关java - Android PhoneGap 1.7 调用 javascript 函数的更多相关文章

  1. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  2. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  3. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  4. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  5. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  6. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  9. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  10. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

随机推荐