Android客户端/服务器INTERNET权限导致应用程序崩溃

时间:2015-01-21 10:44:52

标签: android

我是Android编程新手。

我正在尝试在eclipse中进行非常简单的客户端/服务器TCP通信。服务器端使用java类,客户端使用Android应用程序。我从eclipse启动应用程序,而不是在模拟器上,而是在USB连接的手机上启动。

问题所在。当我从xml清单文件中删除INTERNET权限代码行时,应用程序不会崩溃,但它也不会连接(服务器控制台中没有消息)。但是,如果我确实将INTERNET权限代码放入,则应用程序会崩溃并显示消息Unfortunately APP_NAME has stopped

任何人都可以指出我错过了什么吗?

代码如下:

服务器(java)类:

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

public class Main {

    private static ServerSocket serverSocket = null;
    private static Socket clientSocket;
    private static InputStreamReader inputStreamReader;
    private static BufferedReader bufferedReader;
    private static String message;

    public static void main(String[] args) {

        try {
            serverSocket = new ServerSocket(4444);  //Server socket
        } catch (IOException e) {
            System.out.println("Could not listen on port: 4444");
        }

        System.out.println("Server started. Listening to the port 4444");

        while (true) {
            try {
                clientSocket = serverSocket.accept();   //accept the client connection
                inputStreamReader = new InputStreamReader(clientSocket.getInputStream());
                bufferedReader = new BufferedReader(inputStreamReader); //get the client message
                message = bufferedReader.readLine();

                System.out.println(message);
                inputStreamReader.close();
                clientSocket.close();

            } catch (IOException ex) {
                System.out.println("Problem in message reading");
            }
        }

    }
}

客户端(android)活动文件:

package com.example.simpleclient;


import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class SimpleClientActivity extends Activity {

    private Socket client;
    private PrintWriter printwriter;
    private EditText textField;
    private Button button;
    private String messsage;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        textField = (EditText) findViewById(R.id.editText1); //reference to the text field
        button = (Button) findViewById(R.id.button1);   //reference to the send button

        //Button press event listener
        button.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                messsage = textField.getText().toString(); //get the text message on the text field
                textField.setText("");      //Reset the text field to blank

                try {

                    client = new Socket("127.0.0.1", 4444);  //connect to server
                    printwriter = new PrintWriter(client.getOutputStream(), true);
                    printwriter.write(messsage);  //write the message to output stream

                    printwriter.flush();
                    printwriter.close();
                    client.close();   //closing the connection

                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

    }
}

客户端xml清单文件:

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".SimpleClientActivity"
            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>

- 编辑 - logcat的:

 01-21 21:40:55.012: D/libEGL(17722): loaded /vendor/lib/egl/libEGL_adreno.so
01-21 21:40:55.022: D/libEGL(17722): loaded /vendor/lib/egl/libGLESv1_CM_adreno.so
01-21 21:40:55.042: D/libEGL(17722): loaded /vendor/lib/egl/libGLESv2_adreno.so
01-21 21:40:55.042: I/Adreno-EGL(17722): <qeglDrvAPI_eglInitialize:316>: EGL 1.4 QUALCOMM build:  (CL4169980)
01-21 21:40:55.042: I/Adreno-EGL(17722): OpenGL ES Shader Compiler Version: 17.01.10.SPL
01-21 21:40:55.042: I/Adreno-EGL(17722): Build Date: 09/26/13 Thu
01-21 21:40:55.042: I/Adreno-EGL(17722): Local Branch: 
01-21 21:40:55.042: I/Adreno-EGL(17722): Remote Branch: 
01-21 21:40:55.042: I/Adreno-EGL(17722): Local Patches: 
01-21 21:40:55.042: I/Adreno-EGL(17722): Reconstruct Branch: 
01-21 21:40:55.163: D/OpenGLRenderer(17722): Enabling debug mode 0
01-21 21:40:57.875: D/AndroidRuntime(17722): Shutting down VM
01-21 21:40:57.875: W/dalvikvm(17722): threadid=1: thread exiting with uncaught exception (group=0x4190a898)
01-21 21:40:57.885: E/AndroidRuntime(17722): FATAL EXCEPTION: main
01-21 21:40:57.885: E/AndroidRuntime(17722): android.os.NetworkOnMainThreadException
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1144)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at libcore.io.IoBridge.connect(IoBridge.java:112)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.net.Socket.startupSocket(Socket.java:566)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.net.Socket.tryAllAddresses(Socket.java:127)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.net.Socket.<init>(Socket.java:177)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.net.Socket.<init>(Socket.java:149)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at com.example.simpleclient.SimpleClientActivity$1.onClick(SimpleClientActivity.java:41)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.view.View.performClick(View.java:4475)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.view.View$PerformClick.run(View.java:18786)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.os.Handler.handleCallback(Handler.java:730)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.os.Handler.dispatchMessage(Handler.java:92)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.os.Looper.loop(Looper.java:137)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.app.ActivityThread.main(ActivityThread.java:5419)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.lang.reflect.Method.invokeNative(Native Method)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.lang.reflect.Method.invoke(Method.java:525)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at dalvik.system.NativeStart.main(Native Method)
01-21 21:45:57.988: I/Process(17722): Sending signal. PID: 17722 SIG: 9

1 个答案:

答案 0 :(得分:1)

你应该将你的网络代码包装在后台线程或AsyncTask类中,因为在android中不允许主线程中的网络操作。

例如,您的异步任务代码应如下所示

private class LongOperation extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        try {

                client = new Socket("127.0.0.1", 4444);  //connect to server
                printwriter = new PrintWriter(client.getOutputStream(), true);
                printwriter.write(messsage);  //write the message to output stream

                printwriter.flush();
                printwriter.close();
                client.close();   //closing the connection

            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "Executed";
    }

    @Override
    protected void onPostExecute(String result) {
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText("Executed"); // txt.setText(result);
        // might want to change "executed" for the returned string passed
        // into onPostExecute() but that is upto you
    }

    @Override
    protected void onPreExecute() {}

    @Override
    protected void onProgressUpdate(Void... values) {}
}

并启动异步任务将如下所示

package com.example.simpleclient;


import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class SimpleClientActivity extends Activity {

    private Socket client;
    private PrintWriter printwriter;
    private EditText textField;
    private Button button;
    private String messsage;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        textField = (EditText) findViewById(R.id.editText1); //reference to the text field
        button = (Button) findViewById(R.id.button1);   //reference to the send button

        //Button press event listener
        button.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                messsage = textField.getText().toString(); //get the text message on the text field
                textField.setText("");      //Reset the text field to blank

                new LongOperation().execute("");
        });

    }
}

您可以在活动中定义异步任务