-1

Possible Duplicate:
android.os.NetworkOnMainThreadException

When I try to run my 2nd Activity from a Listener on the 1st Activity, main.xml has a fatal exception. When I take out the runTcpClient(); on the TcpClient Thread() it loads up fine.

I came across UI threads managing using aSyncTask: Android UI aSyncTask

CODE FOR TcpClientJava.java

package com.mesger;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;



public class TcpClient extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    runTcpClient();
    finish();
}

private static final int TCP_SERVER_PORT = 1234;
private void runTcpClient() {
    try {
        Socket s = new Socket("10.0.2.2", TCP_SERVER_PORT);
        BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        //send output msg
        String outMsg = "TCP connecting to " + TCP_SERVER_PORT + System.getProperty("line.separator"); 
        out.write(outMsg);
        out.flush();
        Log.i("TcpClient", "sent: " + outMsg);
        //accept server response
        String inMsg = in.readLine() + System.getProperty("line.separator");
        Log.i("TcpClient", "received: " + inMsg);
        //close connection
        s.close();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } 
}
//replace runTcpClient() at onCreate with this method if you want to run tcp client as a service
private void runTcpClientAsService() {
    Intent lIntent = new Intent(this.getApplicationContext(), TcpClientService.class);
    this.startService(lIntent);
}

}

LOGCAT

11-12 13:41:22.725: D/gralloc_goldfish(738): Emulator without GPU emulation detected.
11-12 13:42:32.409: D/AndroidRuntime(738): Shutting down VM
11-12 13:42:32.409: W/dalvikvm(738): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
11-12 13:42:32.465: E/AndroidRuntime(738): FATAL EXCEPTION: main
11-12 13:42:32.465: E/AndroidRuntime(738): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.i911.emergency.response/com.mesger.TcpClient}: android.os.NetworkOnMainThreadException
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.os.Handler.dispatchMessage(Handler.java:99)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.os.Looper.loop(Looper.java:137)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread.main(ActivityThread.java:4745)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.lang.reflect.Method.invokeNative(Native Method)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.lang.reflect.Method.invoke(Method.java:511)
11-12 13:42:32.465: E/AndroidRuntime(738):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
11-12 13:42:32.465: E/AndroidRuntime(738):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-12 13:42:32.465: E/AndroidRuntime(738):  at dalvik.system.NativeStart.main(Native Method)
11-12 13:42:32.465: E/AndroidRuntime(738): Caused by: android.os.NetworkOnMainThreadException
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
11-12 13:42:32.465: E/AndroidRuntime(738):  at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
11-12 13:42:32.465: E/AndroidRuntime(738):  at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
11-12 13:42:32.465: E/AndroidRuntime(738):  at libcore.io.IoBridge.connect(IoBridge.java:112)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.Socket.startupSocket(Socket.java:566)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.Socket.tryAllAddresses(Socket.java:127)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.Socket.<init>(Socket.java:177)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.Socket.<init>(Socket.java:149)
11-12 13:42:32.465: E/AndroidRuntime(738):  at com.mesger.TcpClient.runTcpClient(TcpClient.java:32)
11-12 13:42:32.465: E/AndroidRuntime(738):  at com.mesger.TcpClient.onCreate(TcpClient.java:25)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.Activity.performCreate(Activity.java:5008)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
11-12 13:42:32.465: E/AndroidRuntime(738):  at     android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
11-12 13:42:32.465: E/AndroidRuntime(738):  ... 11 more
Community
  • 1
  • 1

3 Answers3

2

You should never touch network from the main thread. Implement AsyncTask for network operations.

   private class MyInnerClass extends AsyncTask<String, Void, String> {
       @Override
       protected void onPreExecute() {
       super.onPreExecute();

       }

       @Override
       protected String doInBackground(String params) {

       return "Done";
       }

       @Override
       protected void onPostExecute(String result) {
       super.onPostExecute(result);
       }
   }

Call new MyInnerClass().execute(); from you main Activity and android will automatically call onPreExecute() do whatever you wana do inside this method before your network acess.

Android will then call doInBackground
Do you network related stuff inside doInBackground() and when finished it will automatically call onPostExecute() and the result will be passed as params to this method.

Robin Chander
  • 7,225
  • 3
  • 28
  • 42
1
Caused by: android.os.NetworkOnMainThreadException

You are trying to perform a potentially slow network operation on the main thread, this became a fatal exception in Android 3.0+. Simply move runTcpClient() to a new Thread by using an AsyncTask or Loader.

Here is an example: How to fix android.os.NetworkOnMainThreadException?.


Try this:

class TcpClientTask extends AsyncTask<Void, Void, Void> {
    private static final int TCP_SERVER_PORT = 1234;
    private boolean error = false;

    protected Void doInBackground(Void... arg0) {
        try {
            Socket s = new Socket("10.0.2.2", TCP_SERVER_PORT);
            BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            //send output msg
            String outMsg = "TCP connecting to " + TCP_SERVER_PORT + System.getProperty("line.separator"); 
            out.write(outMsg);
            out.flush();
            Log.i("TcpClient", "sent: " + outMsg);
            //accept server response
            String inMsg = in.readLine() + System.getProperty("line.separator");
            Log.i("TcpClient", "received: " + inMsg);
            //close connection
            s.close();
        } catch (UnknownHostException e) {
            error = true;
            e.printStackTrace();
        } catch (IOException e) {
            error = true;
            e.printStackTrace();
        }
        return null;
    }

    protected void onPostExecute() {
        if(error) {
            // Something bad happened
        }
        else {
            // Success
        }

    }
}

To use it call: new TcpClientTask().execute();


I have 1 more question. String inMsg = in.readLine() + System.getProperty("line.separator"); which receives messages, how would I set it up to get it every 15ms or whatever is stable to keep receiving data.

I'm not certain what you are trying to do. But I noticed you only call readLine() once, if you want to read more than one line, use a loop:

StringBuilder msg = new StringBuilder();
String line;
while((line = in.readLine()) != null) // Keep reading until the end of the file is reached
    msg.append(in.readLine()).append(System.getProperty("line.separator"));

StringBuilders create less overhead when adding Strings together, simply use msg.toString() when you want get the whole message.

Community
  • 1
  • 1
Sam
  • 86,580
  • 20
  • 181
  • 179
  • i saw that post, and I tried to do what they recommeneded and I was unsuccessful? I'm still really new to Android, how would I go about implementing aSyncTask to my code? Also should I change all my Activty to run that way? – Ruben Pizarro Nov 12 '12 at 19:11
  • i'll try it when I get off work and let you know. So excited to finally get this working! Sam. YOU ROCK! – Ruben Pizarro Nov 12 '12 at 19:27
  • I haven't tested this. So let me know if it doesn't work, I'll implement it myself and fix it. – Sam Nov 12 '12 at 19:32
  • When I use this code I get Description Resource Path Location Type The type TcpClient.TcpClientTask must implement the inherited abstract method AsyncTask.doInBackground(Void...) TcpClient.java /mesger/src/com/mesger line 32 Java Problem – Ruben Pizarro Nov 12 '12 at 21:04
  • Use `protected Void doInBackground(Void... arg0) {` and add `return null;` to the end of `doInBackground()`. – Sam Nov 12 '12 at 21:10
  • Hell yeah it works BWHAHAHAHAHAHHAAH! Thanks Sam. – Ruben Pizarro Nov 12 '12 at 21:20
  • Glad I could help, Evil Scientist. :) Please click the check mark in my answer to accept this solution. – Sam Nov 12 '12 at 21:22
  • Hey Sam, I have 1 more question. String inMsg = in.readLine() + System.getProperty("line.separator"); which receives messages, how would I set it up to get it every 15ms or whatever is stable to keep receiving data. – Ruben Pizarro Nov 15 '12 at 07:53
  • I'm not certain what you are trying to do, but I updated my answer with a guess. If you do need a repeating task look into Handlers but understand that 15ms is not much time for a request to be sent out, wait for a reply, and read the response data... – Sam Nov 15 '12 at 17:33
0

Try use Small Piece Of Code.But its not good practice.

    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
   .detectNetwork()
   .permitNetwork() //permit Network access 
   .build());

You Can use AsynTask or any Threading Concept. Its May Help

Sam
  • 1,525
  • 1
  • 9
  • 5
  • Hey Sam. Could use your Ingenious here>> http://stackoverflow.com/questions/13572839/tcp-ip-connects-and-sends-but-doesnt-work-after-initial-sends – Ruben Pizarro Nov 26 '12 at 21:30