我在 ServerSocket 初始化后收到异常“java.lang.RuntimeException: Unable to start activity ComponentInfo”,下面是我的编码,它适用于 Java 应用程序项目,但无法在 android 上运行:
PS:我觉得 In/Out 没那么重要,所以你可以跳过阅读那些,谢谢。
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();
}
}
错误日志:
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
请指教,谢谢!!