【问题标题】:cordova plugin TCPSockets NetworkOnMainThreadException科尔多瓦插件 TCPSockets NetworkOnMainThreadException
【发布时间】:2015-05-20 16:03:56
【问题描述】:

我正在尝试让 Habel 提供的 TCPSockets 插件与 Cordova 5.0 一起使用。这个插件可以在here找到。我可以安装插件,但是当我使用它时,我得到了异常“android.on.NetworkOnMainThreadException”。我已经研究过这个错误,似乎有多种方法可以解决它。任何来自创建新线程或使用 AsyncTask 的东西。我不太确定如何在现有的 java 代码中实现这一点,并希望有人可以帮助解释。我也将此插件用于 IOS 中的同一应用程序,因此该解决方案需要支持 android 和 IOS。有人可以帮我吗?

    package com.habel.sockets;

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;

    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.SSLSocket;
    import javax.net.ssl.SSLSocketFactory;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;

    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.security.cert.X509Certificate;

    import org.json.JSONArray;
    import org.json.JSONException;

    import android.util.Log;

    import org.apache.cordova.CordovaPlugin;
    import org.apache.cordova.PluginResult;
    import org.apache.cordova.CallbackContext;

    public class TCPSockets extends CordovaPlugin { 
        public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
            PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);

    //      Log.d("TCPSockets", "Plugin Called");
            try {
                if (action.equals("sendMessage")) {

                    if (args != null) 
                    {
                        int port  = args.getInt(0);
                        String host = args.getString(1);
                        String message = args.getString(2);
                        int connectionTimeout = args.getInt(3);
                        boolean secureConnection = args.getBoolean(4);

                        r = sendMessage(port, host, message, connectionTimeout, secureConnection);
                        r.setKeepCallback(true);
                    } else {
    //                    return new PluginResult(PluginResult.Status.ERROR, "User did not specify host information");
                        callbackContext.error("User did not specify host information");
                        return true;
                    }
                } else {
    //                return new PluginResult(PluginResult.Status.INVALID_ACTION);
                    callbackContext.error("Invalid Action");
                    return true;
                }
            } 

            catch (JSONException e) {
                Log.d("TCPSockets", "JSONException: " + e.getMessage());
    //          return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
                callbackContext.error("JSON Exception");
                return true;
            }

    //        return r;
            callbackContext.sendPluginResult(r);
            return true;
        }

        public PluginResult sendMessage(int port, String host, String message, int connectionTimeout, boolean secureConnection)
        {
            String reply = "";

            try {           
                // If we don't want secure connections, then use Socket class
                if(!secureConnection)
                {
                    // Not SSL socket
                    Socket sock = new Socket(host, port);
                    Log.d("TCPSockets", "Socket created");
                    sock.setSoTimeout(connectionTimeout); // Time out all actions for 30 seconds

                    PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
                    BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));

                    Log.d("TCPSockets", "Created reader/writer");
                    out.println(message);
                    Log.d("TCPSockets", "Sent message");

                    reply = in.readLine();
                    Log.d("TCPSockets", "Received message: " + reply);

                    out.flush();

                    out.close();
                    in.close();
                    sock.close();
                }
                else // If we want secure connections, then use SSLSocket class
                {               
                    // Create a trust manager that does not validate certificate chains
                    TrustManager[] trustAllCerts = new TrustManager[] {
                        new X509TrustManager() {
                            public X509Certificate[] getAcceptedIssuers() {
                                return null;
                            }

                            public void checkClientTrusted(X509Certificate[] certs, String authType) {
                                // Trust always
                            }

                            public void checkServerTrusted(X509Certificate[] certs, String authType) {
                                // Trust always
                            }
                        }
                    };

                    SSLContext sslContext;

                    try {
                        sslContext = SSLContext.getInstance("SSL");
                    } catch (NoSuchAlgorithmException e) {
                        Log.d("SSLTCPSockets", "No such algorithm");
                        return new PluginResult(PluginResult.Status.IO_EXCEPTION, "Cannot connect to server. Please, try again");
                    }

                    try {
                        sslContext.init(null, trustAllCerts, new SecureRandom());
                    } catch (KeyManagementException e) {
                        Log.d("SSLTCPSockets", "Key manager exception");
                        return new PluginResult(PluginResult.Status.IO_EXCEPTION, "Cannot connect to server. Please, try again");
                    }

                    SSLSocketFactory socketFactory = sslContext.getSocketFactory();
                    SSLSocket socket = (SSLSocket)socketFactory.createSocket(host, port);
                    socket.setSoTimeout(connectionTimeout);
                    socket.setUseClientMode(true);

                    Log.d("SSLTCPSockets", "Connected to status host");

                    SSLSession session = socket.getSession();

                    if (session.isValid())
                    {
                        Log.i(getClass().toString(), "Secure connection");
                        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                        out.println(message);
                        Log.d("SSLTCPSockets", "Sent message");

                        reply = in.readLine();
                        Log.d("SSLTCPSockets", "Received message: " + reply);

                        out.flush();

                        out.close();
                        in.close();
                    }
                    else
                    {
                        Log.d("SSLTCPSockets", "Cannot create a secure connection");
                        return new PluginResult(PluginResult.Status.IO_EXCEPTION, "Cannot connect to server. Please, try again");
                    }

                    socket.close();
                }

                return new PluginResult(PluginResult.Status.OK, reply);
            } 

            catch (UnknownHostException e) {
                Log.d("TCPSockets", "Unknown Host");
                return new PluginResult(PluginResult.Status.IO_EXCEPTION, "Cannot connect to server. Please, try again");
            } 

            catch (java.net.SocketTimeoutException e) {
                Log.d("TCPSockets", "Connection timed out");
                return new PluginResult(PluginResult.Status.IO_EXCEPTION, "Connection timed out. Please, try again");
            }

            catch (IOException e) {
                Log.d("TCPSockets", "IOException");
                return new PluginResult(PluginResult.Status.IO_EXCEPTION, "Unexpected error. Please, try again");
            } 
        }
    }

【问题讨论】:

    标签: android ios cordova android-asynctask tcpsocket


    【解决方案1】:

    下面的代码解决了这个问题。希望它可以帮助其他需要在最新科尔多瓦上进行安全/非安全 TCP 连接的人。

            public class TCPSockets extends CordovaPlugin { 
            @Override
            public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) {      
        //      PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
                final String callbackId = callbackContext.getCallbackId();      
    
        //      Log.d("TCPSockets", "Plugin Called");
                try {
                    if (action.equals("sendMessage")) {
    
                        if (args != null) 
                        {
                            final int port  = args.getInt(0);
                            final String host = args.getString(1);
                            final String message = args.getString(2);
                            final int connectionTimeout = args.getInt(3);
                            final boolean secureConnection = args.getBoolean(4);
    
                            cordova.getThreadPool().execute(new Runnable() {
                                public void run() {
                                    callbackContext.sendPluginResult(sendMessage(port, host, message, connectionTimeout, secureConnection));                            
                                }
                            });                                                                     
                        } else {
        //                    return new PluginResult(PluginResult.Status.ERROR, "User did not specify host information");
                            callbackContext.error("User did not specify host information");
                            return true;
                        }
                    } else {
        //                return new PluginResult(PluginResult.Status.INVALID_ACTION);
                        callbackContext.error("Invalid Action");
                        return true;
                    }
                } 
    
                catch (JSONException e) {
                    Log.d("TCPSockets", "JSONException: " + e.getMessage());
        //          return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
                    callbackContext.error("JSON Exception");
                    return true;
                }
    
        //        return r;
        //      callbackContext.sendPluginResult(r);
                return true;
            }
    
            public PluginResult sendMessage(int port, String host, String message, int connectionTimeout, boolean secureConnection)
            {
                String reply = "";
                PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
    
                try {           
                    // If we don't want secure connections, then use Socket class
                    if(!secureConnection)
                    {
                        // Not SSL socket
                        Socket sock = new Socket(host, port);
                        Log.d("TCPSockets", "Socket created");
                        sock.setSoTimeout(connectionTimeout); // Time out all actions for 30 seconds
    
                        PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
                        BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
    
                        Log.d("TCPSockets", "Created reader/writer");
                        out.println(message);
                        Log.d("TCPSockets", "Sent message");
    
                        reply = in.readLine();
                        Log.d("TCPSockets", "Received message: " + reply);
    
                        out.flush();
    
                        out.close();
                        in.close();
                        sock.close();
                    }
                    else // If we want secure connections, then use SSLSocket class
                    {               
                        // Create a trust manager that does not validate certificate chains
                        TrustManager[] trustAllCerts = new TrustManager[] {
                            new X509TrustManager() {
                                public X509Certificate[] getAcceptedIssuers() {
                                    return null;                                    
                                }
    
                                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                                    // Trust always
                                }
    
                                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                                    // Trust always
                                }
                            }
                        };
    
                        SSLContext sslContext = null;
    
                        try {
                            sslContext = SSLContext.getInstance("SSL");
                        } catch (NoSuchAlgorithmException e) {
                            Log.d("SSLTCPSockets", "No such algorithm");
        //                          return new PluginResult(PluginResult.Status.IO_EXCEPTION, "Cannot connect to server. Please, try again");
                            result = new PluginResult(PluginResult.Status.IO_EXCEPTION, "Cannot connect to server. Please, try again");                 
                            return result;
                        }
    
                        try {
                            sslContext.init(null, trustAllCerts, new SecureRandom());
                        } catch (KeyManagementException e) {
                            Log.d("SSLTCPSockets", "Key manager exception");
        //                          return new PluginResult(PluginResult.Status.IO_EXCEPTION, "Cannot connect to server. Please, try again");
                            result = new PluginResult(PluginResult.Status.IO_EXCEPTION, "Cannot connect to server. Please, try again");
                            return result;
                        }
    
                        SSLSocketFactory socketFactory = sslContext.getSocketFactory();
                        SSLSocket socket = (SSLSocket)socketFactory.createSocket(host, port);
                        socket.setSoTimeout(connectionTimeout);
                        socket.setUseClientMode(true);
    
                        Log.d("SSLTCPSockets", "Connected to host");
    
                        SSLSession session = socket.getSession();
    
                        if (session.isValid())
                        {
                            Log.i(getClass().toString(), "Secure connection");
                            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    
                            out.println(message);
                            Log.d("SSLTCPSockets", "Sent message");
    
                            reply = in.readLine();
                            Log.d("SSLTCPSockets", "Received message: " + reply);
    
                            out.flush();
    
                            out.close();
                            in.close();
                        }
                        else
                        {
                            Log.d("SSLTCPSockets", "Cannot create a secure connection");
        //                          return new PluginResult(PluginResult.Status.IO_EXCEPTION, "Cannot connect to server. Please, try again");
                            result = new PluginResult(PluginResult.Status.IO_EXCEPTION, "Cannot connect to server. Please, try again");
                            return result;
                        }
    
                        socket.close();
                    }
    
                    result = new PluginResult(PluginResult.Status.OK, reply);
                    result.setKeepCallback(true);
                    return result;                  
                } 
    
                catch (UnknownHostException e) {
                    Log.d("TCPSockets", "Unknown Host");
        //                  return new PluginResult(PluginResult.Status.IO_EXCEPTION, "Cannot connect to server. Please, try again");
                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, "Cannot connect to server. Please, try again");
                    return result;
                } 
    
                catch (java.net.SocketTimeoutException e) {
                    Log.d("TCPSockets", "Connection timed out");
        //                  return new PluginResult(PluginResult.Status.IO_EXCEPTION, "Connection timed out. Please, try again");
                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, "Connection timed out. Please, try again");
                    return result;
                }
    
                catch (IOException e) {
                    Log.d("TCPSockets", "IOException");
        //                  return new PluginResult(PluginResult.Status.IO_EXCEPTION, "Unexpected error. Please, try again");
                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, "Unexpected error. Please, try again");
                    return result;
                }       
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-13
      • 1970-01-01
      • 1970-01-01
      • 2016-08-30
      • 2015-05-19
      • 1970-01-01
      • 2015-09-08
      • 2017-12-11
      相关资源
      最近更新 更多