2013-03-12 3 views
1

Я использую AsyncTask для отправки некоторых сообщений на сервер. Этот AsynTask - , определенный в другим классом (CommTask.java) из основного класса активности. Гнездо используется, A WebSocket из weberknecht, создается в способе AsyncTask doInBackground, и у меня есть открытый метод (SendDataToServer) в CommTask.java, то есть используется в основной деятельности через экземпляр класса CommTask.java.android.os.NetworkOnMainThreadException, когда я использую AsyncTask и HTTPS

Я инициализировать экземпляр в основной деятельности перед использованием общественного метода CommTask:

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

и когда у меня есть данные для передачи, то я называю:

commTask.SendDataToServer(...); 

Когда он используется в основной деятельности публичный метод из CommTask.java и сокета использует протокол http

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

исключения не rised, но когда он использует протокол HTTPS

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

android.os.NetworkOnMainThreadException apears.

Любая идея? Почему это может произойти?

Если вам нужно взглянуть на код увидеть это:

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

EDIT:

Полный стек здесь ошибка:

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) 
+0

Просьба опубликовать всю трассировку стека Java, содержащую ваше исключение. – CommonsWare

+0

Подробнее о AsyncTasks читайте в некоторых онлайн-примерах. Вам нужно запустить asynctask, используя asynctask.execute(). Вы не можете просто вызвать функции в своей Задаче и ожидать, что они будут работать в фоновом режиме. –

+0

Ваш общедоступный метод в CommTask вызывается из основного действия основного протектора. – njzk2

ответ

3

Помещенный

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) { } 
} 

в вашем OnStart() метод (или перед AsyncTask выполнить), и она будет решена!

[EDIT] Другие объяснения:

Из документации Google:

Исключение, которое вызывается, когда приложение пытается выполнить сетевую операцию на ее главном потоке. Это делается только для приложений , ориентированных на SDK Honeycomb или выше. Приложения , предназначенные для ранних версий SDK, разрешают создавать сети в своих потоках цикла событий , но это сильно обескураживает.

+0

Это сработало! но это похоже скорее на обходное решение, чем на решение, не так ли? Я хочу еще несколько мнений, прежде чем пометить ваш ответ как решение, если никто ничего не скажет, я сделаю это. Кстати, я думаю, вы имеете в виду метод onPreExecute(), когда вы сказали onStart(), правильно? – Javi

+0

Я отредактировал мое сообщение, вы можете прочитать его;) – StephaneT

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" 

предлагает мне что вы неправильно используете AsyncTask. Вы начинаете его с помощью метода .execute?

Here - разумная статья по этому вопросу. Если вам нужна дополнительная помощь, дайте мне знать, так как нет тонны.

+0

Да, знаю. Я отредактирую основную запись, чтобы было ясно. Я посмотрю на вашу ссылку, спасибо! – Javi

0

Не может быть вашей проблемой, но вы передаете сертификат?

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

Accepting a certificate for HTTPs on Android

+0

Да, у меня есть собственный центр сертификации, установленный на устройстве, который я использовал для подписывания ключей сервера, и телефон без проблем подключается к серверу. В любом случае, спасибо! – Javi

1

Есть идеи? Почему это может произойти?

Трассировка стека говорит, что вы не делаете то, что, по вашему утверждению, делаете. Вы не используете AsyncTask. Вместо этого из метода onClick() вы вызываете статический метод SendDataToServer() класса CommTask, и этот статический метод выполняет сетевой ввод-вывод. Поскольку onClick() будет вызван в основной поток приложения, и поскольку вы не используете AsyncTask или любой другой фоновый поток для этой работы, SendDataToServer() и его сетевой ввод-вывод ведется по основному потоку приложения.

+0

Хм ... Я просто поместил SendDataToServer() в метод OnClick(), потому что мне хотелось ускорить процесс отладки. Исходное исключение, которое было android.os.NetworkOnMainThreadException тоже, поднималось, когда менеджер местоположений имел обновление, менеджер местоположений, который был активирован другой кнопкой onClick() с другой кнопки. – Javi

+0

Здесь вы можете видеть вызовы SendDataToServer(), https://github.com/Javi44/LocAALTOn/blob/WebSockets-Gottox/src/com/android/locaalton/LocAALTOnActivity.java В строке 200 есть одна Я использовал для проверки ошибки, а в строке 338 - это тот, который первоначально вызывал ошибку. Как я могу использовать AsyncTask, если не вызывает метод с использованием экземпляра CommTask? как только он уже инициализирован.Должен ли я создавать новую AsyncTask каждый раз, когда мне есть что отправить? – Javi

+0

@Javi: «Должен ли я создавать новую AsyncTask каждый раз, когда мне есть что отправить?» -- вероятно, да. – CommonsWare

Смежные вопросы