2013-03-12 67 views
1

我正在使用AsyncTask發送一些消息到服務器。這個AsynTask是定義在一個不同的類(CommTask.java)從主要活動類。 插座使用,從weberknecht一個網頁套接字,在的AsyncTask的doInBackground方法創建,並且我在CommTask.java一個公共方法(SendDataToServer),即在主活動使用通過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/"); 

個沒有異常惜售,但是當它使用https

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

android.os.NetworkOnMainThreadException apears。

有什麼想法?爲什麼會發生這種情況?

如果你需要看看在代碼中看到這一點:

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

編輯:

完整的錯誤堆在這裏:

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 2013-03-12 12:54:51

+0

請閱讀更多關於AsyncTasks的信息,並查看一些在線示例。你需要使用asynctask.execute()來運行一個asynctask。你不能只在你的任務中調用函數,並期望它們在後臺運行。 – 2013-03-12 12:57:43

+0

您在CommTask中的公開方法是從主要步驟的主要活動中調用的。 – njzk2 2013-03-12 12:59:42

回答

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之前執行),它會解決的!

[編輯]更多的解釋:

從谷歌的文檔:

當應用程序試圖在其主線程執行 聯網運行時所引發的異常。這僅適用於針對Honeycomb SDK或更高版本的 應用程序。針對早期SDK版本的應用程序 被允許在其主要事件循環線程上進行聯網,但極不鼓勵。

+0

它的工作!但它似乎更像是解決方案,而不是解決方案? 在將答案標記爲解決方案之前,我想要更多的意見,如果沒有人說什麼,我會做。 順便說一句,當你說onStart()時,我認爲你的意思是onExExecute()方法,對吧? – Javi 2013-03-12 13:44:10

+0

我編輯了我的文章,可以閱讀它;) – StephaneT 2013-03-15 09:42:11

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 2013-03-12 13:05:48

1

任何想法?爲什麼會發生這種情況?

堆棧跟蹤表示你沒有做你聲稱要做的事情。您沒有使用AsyncTask。相反,從onClick()方法中,您調用CommTask類上的靜態方法SendDataToServer(),並且該靜態方法正在執行網絡I/O。由於onClick()將在主應用程序線程上調用,並且由於您未在此工作中使用AsyncTask或任何其他後臺線程,因此SendDataToServer()及其網絡I/O正在主應用程序線程上進行。

+0

嗯......我只是把SendDataToServer()放在OnClick()方法中,因爲我想加快調試過程。最初的異常,也就是android.os.NetworkOnMainThreadException,當位置管理器有一個更新時,位置管理器被另一個按鈕上的另一個onClick()按鈕激活。 – Javi 2013-03-12 16:49:19

+0

您可以在這裏看到兩個SendDataToServer()調用, https://github.com/Javi44/LocAALTOn/blob/WebSockets-Gottox/src/com/android/locaalton/LocAALTOnActivity.java 在行200中是一個我已經用來測試錯誤,並且在第338行中,是最初引起錯誤的那個錯誤。 如果不使用CommTask實例調用方法,那麼如何使用AsyncTask?一旦它已經被初始化。我應該每次創建一個新的AsyncTask來發送一些東西嗎? – Javi 2013-03-12 16:54:10

+0

@Javi:「我應該每次創建一個新的AsyncTask來發送一些東西嗎?」 - 可能是。 – CommonsWare 2013-03-12 20:23:12

相關問題