1

我正在尝试编写一个连接到我用 java 编写的服务器的 Android 应用程序。这是我的代码(当我单击按钮时调用):

package me.nrubin29.quiz.student;

import android.app.Activity;
import android.widget.Toast;

import java.io.EOFException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class Connection {

    private Socket socket;
    private Thread reader;
    private ObjectInputStream inputStream;
    private ObjectOutputStream outputStream;

    public void initConnection(final Activity activity, String ip, String port, String name) {
        try {
            Toast.makeText(activity.getApplicationContext(), "Starting connection to " + ip + ":" + Integer.parseInt(port), Toast.LENGTH_SHORT).show();

            socket = new Socket(ip, Integer.parseInt(port));

            Toast.makeText(activity.getApplicationContext(), "Connected!", Toast.LENGTH_SHORT).show();

            outputStream = new ObjectOutputStream(socket.getOutputStream());

            inputStream = new ObjectInputStream(socket.getInputStream());

            outputStream.writeObject(name);

            reader = new Thread(new Runnable() {
                public void run() {
                    while (true) {
                        try {
                            Object in = inputStream.readObject();
                            System.out.println(in);
                        }
                        catch (EOFException e) { Toast.makeText(activity.getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show(); }
                        catch (Exception e) { e.printStackTrace(); }
                    }
                }
            });

            reader.start();
        }
        catch (Exception e) { e.printStackTrace(); }
    }
}

显示第一个 toast(使用正确的端口和 IP),但第二个永远不会出现。手机和电脑都连接到同一个网络,我肯定使用了服务器的正确内部 IP 和端口。

抱歉,如果这是一个nooby问题,我对此很陌生。

更新:

看起来有错误。这里是:

09-23 01:00:00.963: WARN/System.err(890): java.net.SocketException: socket failed: EACCES (Permission denied)
09-23 01:00:00.963: WARN/System.err(890): at libcore.io.IoBridge.socket(IoBridge.java:583)
09-23 01:00:00.963: WARN/System.err(890): at java.net.PlainSocketImpl.create(PlainSocketImpl.java:201)
09-23 01:00:00.972: WARN/System.err(890): at java.net.Socket.startupSocket(Socket.java:559)
09-23 01:00:00.972: WARN/System.err(890): at java.net.Socket.tryAllAddresses(Socket.java:127)
09-23 01:00:00.972: WARN/System.err(890): at java.net.Socket.<init>(Socket.java:177)
09-23 01:00:00.972: WARN/System.err(890): at java.net.Socket.<init>(Socket.java:149)
09-23 01:00:00.972: WARN/System.err(890): at me.nrubin29.quiz.student.Connection.initConnection(Connection.java:22)
09-23 01:00:00.972: WARN/System.err(890): at me.nrubin29.quiz.student.Main$1.onClick(Main.java:35)
09-23 01:00:00.983: WARN/System.err(890): at android.view.View.performClick(View.java:4204)
09-23 01:00:00.983: WARN/System.err(890): at android.view.View$PerformClick.run(View.java:17355)
09-23 01:00:00.983: WARN/System.err(890): at android.os.Handler.handleCallback(Handler.java:725)
09-23 01:00:00.983: WARN/System.err(890): at android.os.Handler.dispatchMessage(Handler.java:92)
09-23 01:00:00.983: WARN/System.err(890): at android.os.Looper.loop(Looper.java:137)
09-23 01:00:00.993: WARN/System.err(890): at android.app.ActivityThread.main(ActivityThread.java:5041)
09-23 01:00:00.993: WARN/System.err(890): at java.lang.reflect.Method.invokeNative(Native Method)
09-23 01:00:00.993: WARN/System.err(890): at java.lang.reflect.Method.invoke(Method.java:511)
09-23 01:00:00.993: WARN/System.err(890): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
09-23 01:00:01.003: WARN/System.err(890): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
09-23 01:00:01.003: WARN/System.err(890): at dalvik.system.NativeStart.main(Native Method)
09-23 01:00:01.013: WARN/System.err(890): Caused by: libcore.io.ErrnoException: socket failed: EACCES (Permission denied)
09-23 01:00:01.013: WARN/System.err(890): at libcore.io.Posix.socket(Native Method)
09-23 01:00:01.013: WARN/System.err(890): at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:181)
09-23 01:00:01.023: WARN/System.err(890): at libcore.io.IoBridge.socket(IoBridge.java:568)
09-23 01:00:01.023: WARN/System.err(890): ... 18 more

更新二:

这是我的 AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="me.nrubin29.quiz.student"
          android:versionCode="1"
          android:versionName="1.0">
    <uses-sdk android:minSdkVersion="15"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <application android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:name=".App">
        <activity android:name="Main"
                  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>

这是另一个新错误:

09-23 01:17:00.618: WARN/System.err(1109): android.os.NetworkOnMainThreadException
09-23 01:17:00.638: WARN/System.err(1109): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
09-23 01:17:00.638: WARN/System.err(1109): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
09-23 01:17:00.648: WARN/System.err(1109): at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
09-23 01:17:00.648: WARN/System.err(1109): at libcore.io.IoBridge.connect(IoBridge.java:112)
09-23 01:17:00.648: WARN/System.err(1109): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
09-23 01:17:00.648: WARN/System.err(1109): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
09-23 01:17:00.668: WARN/System.err(1109): at java.net.Socket.startupSocket(Socket.java:566)
09-23 01:17:00.668: WARN/System.err(1109): at java.net.Socket.tryAllAddresses(Socket.java:127)
09-23 01:17:00.668: WARN/System.err(1109): at java.net.Socket.<init>(Socket.java:177)
09-23 01:17:00.668: WARN/System.err(1109): at java.net.Socket.<init>(Socket.java:149)
09-23 01:17:00.668: WARN/System.err(1109): at me.nrubin29.quiz.student.Connection.initConnection(Connection.java:22)
09-23 01:17:00.688: WARN/System.err(1109): at me.nrubin29.quiz.student.Main$1.onClick(Main.java:35)
09-23 01:17:00.688: WARN/System.err(1109): at android.view.View.performClick(View.java:4204)
09-23 01:17:00.701: WARN/System.err(1109): at android.view.View$PerformClick.run(View.java:17355)
09-23 01:17:00.708: WARN/System.err(1109): at android.os.Handler.handleCallback(Handler.java:725)
09-23 01:17:00.708: WARN/System.err(1109): at android.os.Handler.dispatchMessage(Handler.java:92)
09-23 01:17:00.719: WARN/System.err(1109): at android.os.Looper.loop(Looper.java:137)
09-23 01:17:00.719: WARN/System.err(1109): at android.app.ActivityThread.main(ActivityThread.java:5041)
09-23 01:17:00.738: WARN/System.err(1109): at java.lang.reflect.Method.invokeNative(Native Method)
09-23 01:17:00.738: WARN/System.err(1109): at java.lang.reflect.Method.invoke(Method.java:511)
09-23 01:17:00.748: WARN/System.err(1109): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
09-23 01:17:00.748: WARN/System.err(1109): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
09-23 01:17:00.758: WARN/System.err(1109): at dalvik.system.NativeStart.main(Native Method)
09-23 01:17:00.908: INFO/Choreographer(613): Skipped 71 frames!  The application may be doing too much work on its main thread.

更新 3

将连接内容移至新线程,但现在当我单击完成按钮时没有任何反应(第一个 Toast 未显示):

package me.nrubin29.quiz.student;

import android.app.Activity;
import android.widget.Toast;

import java.io.EOFException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class Connection {

    private Socket socket;
    private Thread reader;
    private ObjectInputStream inputStream;
    private ObjectOutputStream outputStream;

    public void initConnection(final Activity activity, final String ip, final String port, final String name) {
        new Thread(new Runnable() {
            public void run() {
                try {
                    Toast.makeText(activity.getApplicationContext(), "Starting connection to " + ip + ":" + Integer.parseInt(port), Toast.LENGTH_SHORT).show();

                    socket = new Socket(ip, Integer.parseInt(port));

                    Toast.makeText(activity.getApplicationContext(), "Connected!", Toast.LENGTH_SHORT).show();

                    outputStream = new ObjectOutputStream(socket.getOutputStream());

                    inputStream = new ObjectInputStream(socket.getInputStream());

                    outputStream.writeObject(name);

                    reader = new Thread(new Runnable() {
                        public void run() {
                            while (true) {
                                try {
                                    Object in = inputStream.readObject();
                                    System.out.println(in);
                                }
                                catch (EOFException e) { Toast.makeText(activity.getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show(); }
                                catch (Exception e) { e.printStackTrace(); }
                            }
                        }
                    });

                    reader.start();
                }
                catch (Exception e) { e.printStackTrace(); }
            }
        }).start();
    }
}

看起来我们有一个错误:

09-23 01:26:12.939: WARN/ActivityManager(308): Unbind failed: could not find connection for android.os.BinderProxy@40f246d0
09-23 01:26:26.028: WARN/System.err(1276): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
09-23 01:26:26.028: WARN/System.err(1276): at android.os.Handler.<init>(Handler.java:197)
09-23 01:26:26.028: WARN/System.err(1276): at android.os.Handler.<init>(Handler.java:111)
09-23 01:26:26.028: WARN/System.err(1276): at android.widget.Toast$TN.<init>(Toast.java:324)
09-23 01:26:26.059: WARN/System.err(1276): at android.widget.Toast.<init>(Toast.java:91)
09-23 01:26:26.059: WARN/System.err(1276): at android.widget.Toast.makeText(Toast.java:238)
09-23 01:26:26.059: WARN/System.err(1276): at me.nrubin29.quiz.student.Connection$1.run(Connection.java:22)
09-23 01:26:26.059: WARN/System.err(1276): at java.lang.Thread.run(Thread.java:856)
4

2 回答 2

3

它说“权限被拒绝”。你<uses-permission android:name="android.permission.INTERNET"/>的清单文件中有吗?

于 2013-09-23T01:05:31.547 回答
0

此异常是因为您尝试从后台线程显示 UI 元素 (Toast)。

您需要在 UI 线程中创建一个处理程序,然后从方法中发布一条handler消息。run

像这样的东西

在您的 UI 线程中:

final Handler handler = new Handler() {
    @Override
    public void handleMessage(final Message msgs) {
     // Show toast here based on your Message.WHAT Parameter. 
    }
    }

 new Thread(new Runnable() {
  @Override
   public void run() {
    handler.sendEmptyMessage(1);

  }
  }).start();
于 2013-09-23T19:46:29.270 回答