0

I have to send/receive information from a server. I've created a thread (TcpClient is its name) which connects to the server, and it works fine. Now I have to send a simple request to server, and it could send me an answers in the same moment or after 100 seconds. I've implemented it:

   public void request(String s)
     {
      int id = Integer.parseInt(s);
         PrintWriter out = null;
         try
         {
             out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
         }
         catch (IOException e)
         {
             e.printStackTrace();
         }
         out.print("POSREQ "+id);
      out.flush();

     //read part

         StringBuilder reader = new StringBuilder();
         byte[] bytes = new byte[1000];

         int numRead = 0;
         try
         {
          socket.setSoTimeout(70*1000);
          if ((numRead = socket.getInputStream().read(bytes)) >= 0)
          {
                 reader.append(new String(bytes, 0, numRead));
          }
          Log.d("tag:",reader.toString());
         }
          catch (IOException e)
         {
             e.printStackTrace();
         }


     }
 }

in the Thread class. But when I push the button, the application is stopped. What is the problem? I have to make it in other thread or asynctask? Or in a service? Because I've thought to use an asynctask but I have to wait about 100 seconds... This is the logcat:

03-13 09:29:30.018 2024-2122/? E/FaceDetectionService﹕ handleMessage: { what=3 when=0 } 03-13 09:29:30.959 1691-11818/? E/ShotSingle﹕ faceDetect E 03-13 09:29:30.969 2024-2123/? E/FaceDetectionService﹕ onFaceDetection: 0 03-13 09:29:30.969 2024-2063/? E/FaceDetectionService﹕ DONE! 03-13 09:29:30.969 2024-2063/? E/FaceDetectionService﹕ WAIT FOR CALLBACK 03-13 09:29:31.570 2024-2063/? E/FaceDetectionService﹕ No Callback! 03-13 09:29:32.170 2024-2063/? E/FaceDetectionService﹕ No Callback! 03-13 09:29:32.170 2024-2063/? E/FaceDetectionService﹕ DONE! BlinkCount: 0 Retry: 2 03-13 09:29:32.170 2024-2063/? E/FaceDetectionService﹕ Wait for 2 03-13 09:29:32.170 2024-2122/? E/FaceDetectionService﹕ handleMessage: { what=2 when=0 } 03-13 09:29:32.671 1691-11818/? E/ShotSingle﹕ faceDetect X 03-13 09:29:32.681 2024-2063/? E/FaceDetectionService﹕ DONE! 03-13 09:29:32.681 2024-2063/? E/FaceDetectionService﹕ disabled 03-13 09:29:32.681 2024-2063/? E/FaceDetectionService﹕ Wait for 0 03-13 09:29:32.681 2024-2123/? E/FaceDetectionService﹕ onFaceDetection: 0 03-13 09:29:32.681 2024-2122/? E/FaceDetectionService﹕ handleMessage: { what=0 when=-1ms } 03-13 09:29:32.941 2024-2122/? E/FaceDetectionService﹕ handleMessage signal: 0 03-13 09:29:32.941 2024-2063/? E/FaceDetectionService﹕ DONE! 03-13 09:29:33.782 11737-11737/? E/AndroidRuntime﹕ FATAL EXCEPTION: main android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118) at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163) at libcore.io.IoBridge.recvfrom(IoBridge.java:513) at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488) at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46) at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240) at java.io.InputStream.read(InputStream.java:163) at com.example.stefano_pc.tabs.Connection$TCPClient.request(Connection.java:189) at com.example.stefano_pc.tabs.Connection$2.onClick(Connection.java:88) at android.view.View.performClick(View.java:4162) at android.view.View$PerformClick.run(View.java:17082) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4867) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774) at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132) at dalvik.system.NativeStart.main(Native Method) 03-13 09:29:33.862 2024-2043/? E/android.os.Debug﹕ !@Dumpstate > dumpstate -k -t -z -d -o /data/log/dumpstate_app_error 03-13 09:29:40.578 2024-2230/? E/Watchdog﹕ !@Sync 4219

Thank you for your answers.

Francesca
  • 59
  • 1
  • 2
  • 11

1 Answers1

0

Your error is

FATAL EXCEPTION: main android.os.NetworkOnMainThreadException

Network request on android after 2.2 can not be done on the main UI thread.

Calling that method on the your Thread class will not run it on the thread, the method will be run on the thread that calls the method. You need to create a new Thread for your second request and use

start();

I'd suggests looking at Volley or Retrofit.

http://developer.android.com/training/volley/index.html

http://square.github.io/retrofit/

Stuart Campbell
  • 1,141
  • 11
  • 13
  • I know it, in fact I create a new class extends Thread. I do it in the thread, but the app is stopped writing a message "the program is closed" – Francesca Mar 13 '15 at 08:35
  • Not sure I completely understand what you mean. Do you mean the activity is stopped? If so you will need a background service. – Stuart Campbell Mar 13 '15 at 08:38
  • Yes when I'm connecting on tcp it works well, but when I try to send this message, and I press the button, I show the message "Unfortunately app has stopped". So I need an intentservice? It's easy to use? It's the first time I have to use it... – Francesca Mar 13 '15 at 08:42
  • Does pressing the button directly call request()? – Stuart Campbell Mar 13 '15 at 08:45
  • I press the button, in the UI thread and I call request, in the thread class – Francesca Mar 13 '15 at 08:47
  • So the button would call (with your custom class) new Thread().start(); – Stuart Campbell Mar 13 '15 at 08:47
  • No, the button calls: tcpClient.request(ed4.getText().toString()); because before, when I press into another button, I'm connecting via TCP and there is the call new Thread().start()... – Francesca Mar 13 '15 at 08:48
  • That will not run it on the thread. You could go down the direction of loppers and posting handlers extra but bit of over kill for what your down. Simplest was to run things in the background is just. new Thread(new Runnable()).start(); – Stuart Campbell Mar 13 '15 at 08:52
  • Have a quick read of this. http://developer.android.com/reference/android/os/Looper.html – Stuart Campbell Mar 13 '15 at 08:54
  • This is the call for the first button: tcpClient = new TCPClient(IP); tcpClient.start(); May I post it in the second button? Or do you mean to create a second runnable/thread? – Francesca Mar 13 '15 at 08:55
  • My suggestion would be just create a new Thread every time you do a network request. Managing threads is a bit of a pain and over kill for your problem. – Stuart Campbell Mar 13 '15 at 09:04
  • I would really recommend getting to grips with one of the libraries posted above will save you loads of time in the long run. – Stuart Campbell Mar 13 '15 at 09:05
  • Those libraries are useless if you use your own protocol. – greenapps Mar 13 '15 at 09:21
  • I have used this one for websockets before it seems pretty good as well. Should fit your problem. https://github.com/koush/AndroidAsync – Stuart Campbell Mar 13 '15 at 09:52
  • But I don't understand how to listen the message of the server... – Francesca Mar 13 '15 at 09:53
  • Look at the SocketIOClient and client.setStringCallback – Stuart Campbell Mar 13 '15 at 09:57
  • It's wrong to use: socket.setSoTimeout(100000); ? – Francesca Mar 13 '15 at 10:28