1

I am getting the Exception "java.lang.RuntimeException: Unable to start activity ComponentInfo" after ServerSocket Initialized, below is my coding, it works in Java application project, but failed to run on android:

PS: I think In/Out is not that important, so you may skip to read those, thanks.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.test"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.INTERNET"></uses-permission> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission> 
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.test.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

com.example.test.MainActivity.java

package com.example.test;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.v("blah", "blah blah");

        try {
            // create socket
            int port = 4444;
            ServerSocket serverSocket = new ServerSocket(port);
            Log.v("blah", "Started server on port " + port);

            // repeatedly wait for connections, and process
            while (true) {
                // a "blocking" call which waits until a connection is requested
                Socket clientSocket = serverSocket.accept();
                Log.v("blah", "Accepted connection from client");

                // open up IO streams
                In  in  = new In (clientSocket);
                Out out = new Out(clientSocket);

                // waits for data and reads it in until connection dies
                // readLine() blocks until the server receives a new line from client
                String s;
                while ((s = in.readLine()) != null) {
                    out.println(s);
                }

                // close IO streams, then socket
                Log.v("blah", "Closing connection with client");
                out.close();
                in.close();
                clientSocket.close();
            }
        } catch (IOException e) {
            Log.v("blah", e.getMessage());
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

com.example.test.In

package com.example.test;
/*************************************************************************
 *  Compilation:  javac In.java
 *  Execution:    java In   (basic test --- see source for required files)
 *
 *  Reads in data of various types from standard input, files, and URLs.
 *
 *************************************************************************/

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Scanner;
import java.util.regex.Pattern;

/**
 *  <i>Input</i>. This class provides methods for reading strings
 *  and numbers from standard input, file input, URLs, and sockets. 
 *  <p>
 *  The Locale used is: language = English, country = US. This is consistent
 *  with the formatting conventions with Java floating-point literals,
 *  command-line arguments (via {@link Double#parseDouble(String)})
 *  and standard output. 
 *  <p>
 *  For additional documentation, see 
 *  <a href="http://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of
 *  <i>Introduction to Programming in Java: An Interdisciplinary Approach</i> 
 *  by Robert Sedgewick and Kevin Wayne.
 *  <p>
 *  Like {@link Scanner}, reading a token also consumes preceding Java
 *  whitespace, reading a full line consumes
 *  the following end-of-line delimeter, while reading a character consumes
 *  nothing extra. 
 *  <p>
 *  Whitespace is defined in {@link Character#isWhitespace(char)}. Newlines
 *  consist of \n, \r, \r\n, and Unicode hex code points 0x2028, 0x2029, 0x0085;
 *  see <tt><a href="http://www.docjar.com/html/api/java/util/Scanner.java.html">
 *  Scanner.java</a></tt> (NB: Java 6u23 and earlier uses only \r, \r, \r\n).
 */
public final class In {

    private Scanner scanner;

    /*** begin: section (1 of 2) of code duplicated from In to StdIn */

    // assume Unicode UTF-8 encoding
    private static final String charsetName = "UTF-8";

    // assume language = English, country = US for consistency with System.out.
    private static final java.util.Locale usLocale = 
        new java.util.Locale("en", "US");

    // the default token separator; we maintain the invariant that this value 
    // is held by the scanner's delimiter between calls
    private static final Pattern WHITESPACE_PATTERN
        = Pattern.compile("\\p{javaWhitespace}+");

    // makes whitespace characters significant 
    private static final Pattern EMPTY_PATTERN
        = Pattern.compile("");

    // used to read the entire input. source:
    // http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html
    private static final Pattern EVERYTHING_PATTERN
        = Pattern.compile("\\A");

    /*** end: section (1 of 2) of code duplicated from In to StdIn */

   /**
     * Create an input stream from standard input.
     */
    public In() {
        scanner = new Scanner(new BufferedInputStream(System.in), charsetName);
        scanner.useLocale(usLocale);
    }

   /**
     * Create an input stream from a socket.
     */
    public In(java.net.Socket socket) {
        try {
            InputStream is = socket.getInputStream();
            scanner = new Scanner(new BufferedInputStream(is), charsetName);
            scanner.useLocale(usLocale);
        }
        catch (IOException ioe) {
            System.err.println("Could not open " + socket);
        }
    }

   /**
     * Create an input stream from a URL.
     */
    public In(URL url) {
        try {
            URLConnection site = url.openConnection();
            InputStream is     = site.getInputStream();
            scanner            = new Scanner(new BufferedInputStream(is), charsetName);
            scanner.useLocale(usLocale);
        }
        catch (IOException ioe) {
            System.err.println("Could not open " + url);
        }
    }

   /**
     * Create an input stream from a file.
     */
    public In(File file) {
        try {
            scanner = new Scanner(file, charsetName);
            scanner.useLocale(usLocale);
        }
        catch (IOException ioe) {
            System.err.println("Could not open " + file);
        }
    }


   /**
     * Create an input stream from a filename or web page name.
     */
    public In(String s) {
        try {
            // first try to read file from local file system
            File file = new File(s);
            if (file.exists()) {
                scanner = new Scanner(file, charsetName);
                scanner.useLocale(usLocale);
                return;
            }

            // next try for files included in jar
            URL url = getClass().getResource(s);

            // or URL from web
            if (url == null) { url = new URL(s); }

            URLConnection site = url.openConnection();
            InputStream is     = site.getInputStream();
            scanner            = new Scanner(new BufferedInputStream(is), charsetName);
            scanner.useLocale(usLocale);
        }
        catch (IOException ioe) {
            System.err.println("Could not open " + s);
        }
    }

    /**
     * Create an input stream from a given Scanner source; use with 
     * <tt>new Scanner(String)</tt> to read from a string.
     * <p>
     * Note that this does not create a defensive copy, so the
     * scanner will be mutated as you read on. 
     */
    public In(Scanner scanner) {
        this.scanner = scanner;
    }

    /**
     * Does the input stream exist?
     */
    public boolean exists()  {
        return scanner != null;
    }

    /*** begin: section (2 of 2) of code duplicated from In to StdIn,
      *  with all methods changed from "public" to "public static" ***/

   /**
     * Is the input empty (except possibly for whitespace)? Use this
     * to know whether the next call to {@link #readString()}, 
     * {@link #readDouble()}, etc will succeed.
     */
    public boolean isEmpty() {
        return !scanner.hasNext();
    }

   /**
     * Does the input have a next line? Use this to know whether the
     * next call to {@link #readLine()} will succeed. <p> Functionally
     * equivalent to {@link #hasNextChar()}.
     */
    public boolean hasNextLine() {
        return scanner.hasNextLine();
    }

    /**
     * Is the input empty (including whitespace)? Use this to know 
     * whether the next call to {@link #readChar()} will succeed. <p> Functionally
     * equivalent to {@link #hasNextLine()}.
     */
    public boolean hasNextChar() {
        scanner.useDelimiter(EMPTY_PATTERN);
        boolean result = scanner.hasNext();
        scanner.useDelimiter(WHITESPACE_PATTERN);
        return result;
    }


   /**
     * Read and return the next line.
     */
    public String readLine() {
        String line;
        try                 { line = scanner.nextLine(); }
        catch (Exception e) { line = null;               }
        return line;
    }

    /**
     * Read and return the next character.
     */
    public char readChar() {
        scanner.useDelimiter(EMPTY_PATTERN);
        String ch = scanner.next();
        assert (ch.length() == 1) : "Internal (Std)In.readChar() error!"
            + " Please contact the authors.";
        scanner.useDelimiter(WHITESPACE_PATTERN);
        return ch.charAt(0);
    }  


   /**
     * Read and return the remainder of the input as a string.
     */
    public String readAll() {
        if (!scanner.hasNextLine())
            return "";

        String result = scanner.useDelimiter(EVERYTHING_PATTERN).next();
        // not that important to reset delimeter, since now scanner is empty
        scanner.useDelimiter(WHITESPACE_PATTERN); // but let's do it anyway
        return result;
    }


   /**
     * Read and return the next string.
     */
    public String readString() {
        return scanner.next();
    }

   /**
     * Read and return the next int.
     */
    public int readInt() {
        return scanner.nextInt();
    }

   /**
     * Read and return the next double.
     */
    public double readDouble() {
        return scanner.nextDouble();
    }

   /**
     * Read and return the next float.
     */
    public float readFloat() {
        return scanner.nextFloat();
    }

   /**
     * Read and return the next long.
     */
    public long readLong() {
        return scanner.nextLong();
    }

   /**
     * Read and return the next short.
     */
    public short readShort() {
        return scanner.nextShort();
    }

   /**
     * Read and return the next byte.
     */
    public byte readByte() {
        return scanner.nextByte();
    }

    /**
     * Read and return the next boolean, allowing case-insensitive
     * "true" or "1" for true, and "false" or "0" for false.
     */
    public boolean readBoolean() {
        String s = readString();
        if (s.equalsIgnoreCase("true"))  return true;
        if (s.equalsIgnoreCase("false")) return false;
        if (s.equals("1"))               return true;
        if (s.equals("0"))               return false;
        throw new java.util.InputMismatchException();
    }

    /**
     * Read all strings until the end of input is reached, and return them.
     */
    public String[] readAllStrings() {
        // we could use readAll.trim().split(), but that's not consistent
        // since trim() uses characters 0x00..0x20 as whitespace
        String[] tokens = WHITESPACE_PATTERN.split(readAll());
        if (tokens.length == 0 || tokens[0].length() > 0)
            return tokens;
        String[] decapitokens = new String[tokens.length-1];
        for (int i = 0; i < tokens.length-1; i++)
            decapitokens[i] = tokens[i+1];
        return decapitokens;
    }

    /**
     * Read all ints until the end of input is reached, and return them.
     */
    public int[] readAllInts() {
        String[] fields = readAllStrings();
        int[] vals = new int[fields.length];
        for (int i = 0; i < fields.length; i++)
            vals[i] = Integer.parseInt(fields[i]);
        return vals;
    }

    /**
     * Read all doubles until the end of input is reached, and return them.
     */
    public double[] readAllDoubles() {
        String[] fields = readAllStrings();
        double[] vals = new double[fields.length];
        for (int i = 0; i < fields.length; i++)
            vals[i] = Double.parseDouble(fields[i]);
        return vals;
    }

    /*** end: section (2 of 2) of code duplicated from In to StdIn */

   /**
     * Close the input stream.
     */
    public void close() {
        scanner.close();  
    }

    /**
     * Reads all ints from a file 
     * @deprecated Clearer to use 
     * <tt>new In(filename)</tt>.{@link #readAllInts()}
     */
    public static int[] readInts(String filename) {
        return new In(filename).readAllInts();
    }

   /**
     * Reads all doubles from a file
     * @deprecated Clearer to use 
     * <tt>new In(filename)</tt>.{@link #readAllDoubles()}
     */
    public static double[] readDoubles(String filename) {
        return new In(filename).readAllDoubles();
    }

   /**
     * Reads all strings from a file
     * @deprecated Clearer to use 
     * <tt>new In(filename)</tt>.{@link #readAllStrings()}
     */
    public static String[] readStrings(String filename) {
        return new In(filename).readAllStrings();
    }

    /**
     * Reads all ints from stdin 
     * @deprecated Clearer to use {@link StdIn#readAllInts()}
     */
    public static int[] readInts() {
        return new In().readAllInts();
    }

   /**
     * Reads all doubles from stdin
     * @deprecated Clearer to use {@link StdIn#readAllDoubles()}
     */
    public static double[] readDoubles() {
        return new In().readAllDoubles();
    }

   /**
     * Reads all strings from stdin
     * @deprecated Clearer to use {@link StdIn#readAllStrings()}
     */
    public static String[] readStrings() {
        return new In().readAllStrings();
    }

   /**
     * Test client.
     */
    public static void main(String[] args) {
        In in;
        String urlName = "http://introcs.cs.princeton.edu/stdlib/InTest.txt";

        // read from a URL
        System.out.println("readAll() from URL " + urlName);
        System.out.println("---------------------------------------------------------------------------");
        try {
            in = new In(urlName);
            System.out.println(in.readAll());
        }
        catch (Exception e) { System.out.println(e); }
        System.out.println();

        // read one line at a time from URL
        System.out.println("readLine() from URL " + urlName);
        System.out.println("---------------------------------------------------------------------------");
        try {
            in = new In(urlName);
            while (!in.isEmpty()) {
                String s = in.readLine();
                System.out.println(s);
            }
        }
        catch (Exception e) { System.out.println(e); }
        System.out.println();

        // read one string at a time from URL
        System.out.println("readString() from URL " + urlName);
        System.out.println("---------------------------------------------------------------------------");
        try {
            in = new In(urlName);
            while (!in.isEmpty()) {
                String s = in.readString();
                System.out.println(s);
            }
        }
        catch (Exception e) { System.out.println(e); }
        System.out.println();


        // read one line at a time from file in current directory
        System.out.println("readLine() from current directory");
        System.out.println("---------------------------------------------------------------------------");
        try {
            in = new In("./InTest.txt");
            while (!in.isEmpty()) {
                String s = in.readLine();
                System.out.println(s);
            }
        }
        catch (Exception e) { System.out.println(e); }
        System.out.println();


        // read one line at a time from file using relative path
        System.out.println("readLine() from relative path");
        System.out.println("---------------------------------------------------------------------------");
        try {
            in = new In("../stdlib/InTest.txt");
            while (!in.isEmpty()) {
                String s = in.readLine();
                System.out.println(s);
            }
        }
        catch (Exception e) { System.out.println(e); }
        System.out.println();

        // read one char at a time
        System.out.println("readChar() from file");
        System.out.println("---------------------------------------------------------------------------");
        try {
            in = new In("InTest.txt");
            while (!in.isEmpty()) {
                char c = in.readChar();
                System.out.print(c);
            }
        }
        catch (Exception e) { System.out.println(e); }
        System.out.println();
        System.out.println();

        // read one line at a time from absolute OS X / Linux path
        System.out.println("readLine() from absolute OS X / Linux path");
        System.out.println("---------------------------------------------------------------------------");
        in = new In("/n/fs/introcs/www/java/stdlib/InTest.txt");
        try {
            while (!in.isEmpty()) {
                String s = in.readLine();
                System.out.println(s);
            }
        }
        catch (Exception e) { System.out.println(e); }
        System.out.println();


        // read one line at a time from absolute Windows path
        System.out.println("readLine() from absolute Windows path");
        System.out.println("---------------------------------------------------------------------------");
        try {
            in = new In("G:\\www\\introcs\\stdlib\\InTest.txt");
            while (!in.isEmpty()) {
                String s = in.readLine();
                System.out.println(s);
            }
            System.out.println();
        }
        catch (Exception e) { System.out.println(e); }
        System.out.println();

    }

}

com.example.text.out

package com.example.test;
/*************************************************************************
 *  Compilation:  javac Out.java
 *  Execution:    java Out
 *
 *  Writes data of various types to: stdout, file, or socket.
 *
 *************************************************************************/


import java.io.IOException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class Out {
    private PrintWriter out;

    // for stdout
    public Out(OutputStream os) { out = new PrintWriter(os, true); }
    public Out()                { this(System.out);                }

    // for Socket output
    public Out(Socket socket) {
        try                     { out = new PrintWriter(socket.getOutputStream(), true); }
        catch (IOException ioe) { ioe.printStackTrace();                                 }
    }

    // for file output
    public Out(String s) {
        try                     { out = new PrintWriter(new FileOutputStream(s), true);  }
        catch(IOException ioe)  { ioe.printStackTrace();                                 }
    }

    public void close() { out.close(); }


    public void println()          { out.println();  out.flush(); }
    public void println(Object x)  { out.println(x); out.flush(); }
    public void println(boolean x) { out.println(x); out.flush(); }
    public void println(char x)    { out.println(x); out.flush(); }
    public void println(double x)  { out.println(x); }
    public void println(float x)   { out.println(x); }
    public void println(int x)     { out.println(x); }
    public void println(long x)    { out.println(x); }

    public void print()            {                 out.flush(); }
    public void print(Object x)    { out.print(x);   out.flush(); }
    public void print(boolean x)   { out.print(x);   out.flush(); }
    public void print(char x)      { out.print(x);   out.flush(); }
    public void print(double x)    { out.print(x);   out.flush(); }
    public void print(float x)     { out.print(x);   out.flush(); }
    public void print(int x)       { out.print(x);   out.flush(); }
    public void print(long x)      { out.print(x);   out.flush(); }


    // This method is just here to test the class
    public static void main (String[] args) {
        Out out;
        String s;

        // write to stdout
        out = new Out();
        out.println("Test 1");
        out.close();

        // write to a file
        out= new Out("test.txt");
        out.println("Test 2");
        out.close();
    }

}

Error Log:

08-11 03:18:12.085: V/blah(11879): blah blah
08-11 03:18:12.085: V/blah(11879): Started server on port 4444
08-11 03:18:13.190: D/dalvikvm(11879): threadid=1: still suspended after undo (sc=1 dc=1)
08-11 03:18:24.900: D/AndroidRuntime(11879): Shutting down VM
08-11 03:18:24.900: W/dalvikvm(11879): threadid=1: thread exiting with uncaught exception (group=0x414ae2a0)
08-11 03:18:24.910: E/AndroidRuntime(11879): FATAL EXCEPTION: main
08-11 03:18:24.910: E/AndroidRuntime(11879): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test/com.example.test.MainActivity}: android.os.NetworkOnMainThreadException
08-11 03:18:24.910: E/AndroidRuntime(11879):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2100)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at android.app.ActivityThread.access$600(ActivityThread.java:140)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at android.os.Looper.loop(Looper.java:137)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at android.app.ActivityThread.main(ActivityThread.java:4898)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at java.lang.reflect.Method.invokeNative(Native Method)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at java.lang.reflect.Method.invoke(Method.java:511)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at dalvik.system.NativeStart.main(Native Method)
08-11 03:18:24.910: E/AndroidRuntime(11879): Caused by: android.os.NetworkOnMainThreadException
08-11 03:18:24.910: E/AndroidRuntime(11879):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at libcore.io.BlockGuardOs.accept(BlockGuardOs.java:54)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:98)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at java.net.ServerSocket.implAccept(ServerSocket.java:202)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at java.net.ServerSocket.accept(ServerSocket.java:127)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at com.example.test.MainActivity.onCreate(MainActivity.java:29)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at android.app.Activity.performCreate(Activity.java:5206)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
08-11 03:18:24.910: E/AndroidRuntime(11879):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2064)
08-11 03:18:24.910: E/AndroidRuntime(11879):    ... 11 more

Please advice, thanks you!!

Steve Lam
  • 499
  • 1
  • 10
  • 27

2 Answers2

1

Android has a restriction in which you cannot do any kind of network operation on main thread. Your provided error log says the same. You need to use AsyncTask for that. Another stackoverflow link as a working example is here.

The main problem starts here in your main activity:

Socket clientSocket = serverSocket.accept();
Community
  • 1
  • 1
Abdullah Shoaib
  • 2,065
  • 2
  • 18
  • 26
0

Don't do such network related work inside UI thread. Always do network based work inside AsyncTask and call it from UI thread.

Here's the page that give the reasons why we get the errors - here

Vinu V
  • 87
  • 1
  • 3
  • 11