1

I am using an AsyncTask to send some messages to a server. This AsynTask is defined in a different class (CommTask.java) from the main activity class. The socket used, a websocket from weberknecht, is created in the doInBackground method of the AsyncTask, and I have a public method (SendDataToServer) in the CommTask.java, that is used in the main activity through an instance from the class CommTask.java.

I initialize the instance in the main activity before using the public method of CommTask:

commTask = new CommTask(serverIpAddress, socket, textStatus);
commTask.execute();

and when I have data to send, then I call:

commTask.SendDataToServer(...);

When it is used in the main activity the public method from CommTask.java and the socket uses http protocol

socket = new SocketIO("http://"+this.serverIpAddress+":3000/");

no exceptions are rised, but when it uses the https

 socket = new SocketIO("https://"+this.serverIpAddress+":3000/");

android.os.NetworkOnMainThreadException apears.

Any idea? Why can this be happening?

If you need to take a look to the code see this:

https://github.com/Javi44/LocAALTOn/tree/WebSockets-Gottox/src/com/android/locaalton

EDIT:

Full error stack here:

03-12 15:14:36.090: W/System.err(27088): android.os.NetworkOnMainThreadException
03-12 15:14:36.100: W/System.err(27088):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
03-12 15:14:36.100: W/System.err(27088):    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:686)
03-12 15:14:36.100: W/System.err(27088):    at java.io.BufferedOutputStream.flushInternal(BufferedOutputStream.java:185)
03-12 15:14:36.100: W/System.err(27088):    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:85)
03-12 15:14:36.100: W/System.err(27088):    at de.roderick.weberknecht.WebSocketConnection.send(WebSocketConnection.java:165)
03-12 15:14:36.100: W/System.err(27088):    at io.socket.WebsocketTransport.send(WebsocketTransport.java:137)
03-12 15:14:36.100: W/System.err(27088):    at io.socket.IOConnection.sendPlain(IOConnection.java:452)
03-12 15:14:36.100: W/System.err(27088):    at io.socket.IOConnection.emit(IOConnection.java:825)
03-12 15:14:36.100: W/System.err(27088):    at io.socket.SocketIO.emit(SocketIO.java:236)
03-12 15:14:36.100: W/System.err(27088):    at com.android.locaalton.CommTask.SendDataToServer(CommTask.java:137)
03-12 15:14:36.105: W/System.err(27088):    at com.android.locaalton.LocAALTOnActivity$2.onClick(LocAALTOnActivity.java:200)
03-12 15:14:36.105: W/System.err(27088):    at android.view.View.performClick(View.java:4211)
03-12 15:14:36.105: W/System.err(27088):    at android.view.View$PerformClick.run(View.java:17267)
03-12 15:14:36.105: W/System.err(27088):    at android.os.Handler.handleCallback(Handler.java:615)
03-12 15:14:36.105: W/System.err(27088):    at android.os.Handler.dispatchMessage(Handler.java:92)
03-12 15:14:36.105: W/System.err(27088):    at android.os.Looper.loop(Looper.java:137)
03-12 15:14:36.105: W/System.err(27088):    at android.app.ActivityThread.main(ActivityThread.java:4898)
03-12 15:14:36.105: W/System.err(27088):    at java.lang.reflect.Method.invokeNative(Native Method)
03-12 15:14:36.105: W/System.err(27088):    at java.lang.reflect.Method.invoke(Method.java:511)
03-12 15:14:36.105: W/System.err(27088):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
03-12 15:14:36.105: W/System.err(27088):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
03-12 15:14:36.105: W/System.err(27088):    at dalvik.system.NativeStart.main(Native Method)
Javi
  • 139
  • 1
  • 2
  • 12
  • Please post the entire Java stack trace containing your exception. – CommonsWare Mar 12 '13 at 12:54
  • Please read more about AsyncTasks and check some online examples. You need to run an asynctask using asynctask.execute(). You can not just call the functions in your Task and expect them to run in the background. – Sherif elKhatib Mar 12 '13 at 12:57
  • your public method in CommTask is called from the main activity on the main tread. – njzk2 Mar 12 '13 at 12:59
  • I have added the stack and an explanation of how I use the AsyncTask, I forgot to tell that I call the execute() before. – Javi Mar 12 '13 at 13:20

5 Answers5

3

Put

if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 9) {
    try {
        // StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.LAX);
           Class<?> strictModeClass = Class.forName("android.os.StrictMode", true, Thread.currentThread()
                        .getContextClassLoader());
           Class<?> threadPolicyClass = Class.forName("android.os.StrictMode$ThreadPolicy", true, Thread.currentThread()
                        .getContextClassLoader());
           Field laxField = threadPolicyClass.getField("LAX");
           Method setThreadPolicyMethod = strictModeClass.getMethod("setThreadPolicy", threadPolicyClass);
                setThreadPolicyMethod.invoke(strictModeClass, laxField.get(null));
    } 
    catch (Exception e) { }
}

in your onStart() method (or before your AsyncTask execute) and it'll solved !

[EDIT] More explanations :

From Google’s documentation:

The exception that is thrown when an application attempts to perform a networking operation on its main thread. This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it’s heavily discouraged.

StephaneT
  • 479
  • 5
  • 11
  • It worked! but it is seems more like workaround than a solution, isn't it? I want some more opinions before marking your answer as the solution, if nobody says nothing else I will do it. By the way, I think you mean onPreExecute() method when you said onStart(), right? – Javi Mar 12 '13 at 13:44
1

Try my answer here,

https://stackoverflow.com/a/9104893/557179

Your issue is that the network request is done on the main thread.

Community
  • 1
  • 1
Nikola Despotoski
  • 49,966
  • 15
  • 119
  • 148
1

Any idea? Why can this be happening?

The stack trace says that you are not doing what you claim to be doing. You are not using an AsyncTask. Instead, from an onClick() method, you are calling a static SendDataToServer() method on a CommTask class, and that static method is doing the network I/O. Since onClick() will be called on the main application thread, and since you are not using an AsyncTask or any other background thread for this work, SendDataToServer() and its network I/O is being conducted on the main application thread.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Hmmm... I just put the SendDataToServer() inside the OnClick() method because I wanted to accelerate the debug proccess. The initial exception, that was android.os.NetworkOnMainThreadException too, was raising when a location manager had an update, location manager that was activated with another onClick() button from another button. – Javi Mar 12 '13 at 16:49
  • You can see both SendDataToServer() calls in here, https://github.com/Javi44/LocAALTOn/blob/WebSockets-Gottox/src/com/android/locaalton/LocAALTOnActivity.java In the line 200 is the one I have used to test the error, and in the line 338, is the one that was raising the error initially. How can I use then the AsyncTask if is not calling the method using the CommTask instance? once it is already initialized. Should I create a new AsyncTask each time that I have something to send? – Javi Mar 12 '13 at 16:54
  • @Javi: "Should I create a new AsyncTask each time that I have something to send?" -- probably yes. – CommonsWare Mar 12 '13 at 20:23
  • But, when you create an AsyncTask it is created a new thread, and even if you call the method cancel() it remains there... and I am going to send many messages, isn't it that worse than sending the messages from the main activity? – Javi Mar 13 '13 at 07:32
0
"and I have a public method in the CommTask.java, that is used in 
the main activity through an instance from the class CommTask.java"

suggests to me that you're using the AsyncTask incorrectly. Are you starting it using the proper .execute method?

Here is a reasonable article on the subject. If you need more help let me know since there isn't a ton to go on.

chris-tulip
  • 1,840
  • 1
  • 15
  • 22
  • Yes, I do. I will edit the main post to make it clear. I'll take a look to your link, thanks! – Javi Mar 12 '13 at 13:05
0

Might not be your issue, but are you passing a certificate?

http://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html

Accepting a certificate for HTTPs on Android

Community
  • 1
  • 1
dberm22
  • 3,187
  • 1
  • 31
  • 46
  • Yep, I have my own certification authority installed on the device, which I have used to sign the server keys, and the phone connects with the server without problem. Thank you anyway! – Javi Mar 12 '13 at 13:12