我尝试发送json时将NullPointerException插入我的套接字

时间:2018-09-09 21:00:07

标签: java android

我正在做一个服务器-客户端项目,当我尝试发送JSON文件时,客户端出了点问题。服务器-方面还可以,并且可以正常工作。 Logcat中的错误表明我在缓冲读取器中的问题。对不起我的英语,我只是学生_。

错误

Process: com.dontknow.myapplication231, PID: 5782
java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.OutputStream java.net.Socket.getOutputStream()' on a null object reference
    at com.dontknow.myapplication231.User.SendDataToServer.doInBackground(SendDataToServer.java:67)
    at com.dontknow.myapplication231.User.SendDataToServer.<init>(SendDataToServer.java:30)
    at com.dontknow.myapplication231.User.MainActivity$1.onClick(MainActivity.java:52)
    at android.view.View.performClick(View.java:5637)
    at android.view.View$PerformClick.run(View.java:22429)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6119)
    at java.lang.reflect.Method.invoke(Native Method)
    at 
    com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
    09-09 12:00:20.960 559-1769/system_process E/EGL_emulation: tid 1769: 
    eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH)
    09-09 12:00:21.694 598-598/? E/EGL_emulation: tid 598: eglCreateSyncKHR(1669): 
    error 0x3004 (EGL_BAD_ATTRIBUTE)
    09-09 12:00:22.375 1221-1276/com.android.launcher3 E/EGL_emulation: tid 1276: 
    eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH)
    09-09 12:05:20.858 559-1137/system_process E/JavaBinder: !!! FAILED BINDER 
    TRANSACTION !!!  (parcel size = 104)
    09-09 12:05:20.862 559-1137/system_process E/JavaBinder: !!! FAILED BINDER 
    TRANSACTION !!!  (parcel size = 108)

我的客户端使用AsyncTask(我从editName.getText.toString获得的名称和密码与密码相同

class SendDataToServer extends AsyncTask<Void,Void,Void> {
private Socket socket;
private String name;
private String password;
private static final String debug = "debug";
private static final String info = "INFO";
protected static String server_IP = "192.168.0.101";
protected static final int server_Port = 8607;

   SendDataToServer(String name, String password){
   this.name = name;
   this.password = password;
   onPreExecute();
   doInBackground();
   onPreExecute();

  }

@Override
protected void onPreExecute() {
   Thread thread = new Thread(new Runnable() {
       @Override
       public void run() {
           try {

               Log.i(debug,"Attempt to connect to server");

               socket = new Socket(server_IP,server_Port);
               Log.i(debug,"Connection established");

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

       }
   });
    thread.start();
    }

@Override
protected Void doInBackground(Void... voids) {
    JSONObject user = new JSONObject();
    try {
        user.put("name", name);
        user.put("name",password);

    } catch (JSONException e) {
        e.printStackTrace();
    }
    try{
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bw.write(String.valueOf(user));
        bw.newLine();
        bw.newLine();
        bw.flush();
        Log.i(info,"JSON has sent");


        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        br.readLine();
        Log.i(info,br.readLine());

    }catch (IOException e) {
        Log.e(debug,"Failed");
    }


    return null;
}

@Override
protected void onPostExecute(Void aVoid) {
    try {
        if(socket!=null){
            socket.close();
        }
    } catch (IOException e) {
        Log.e(debug,"Failed");
    }
 }
}

我真的很想知道这个问题是什么以及如何解决。感谢帮助。

2 个答案:

答案 0 :(得分:0)

我建议您阅读AsyncTask-Android-Example的一些答案。

然后,您需要知道类似的方法:

  1. onPreExecute();
  2. doInBackground();
  3. onPreExecute();

被自动调用。

所以您应该将代码更改为此:

class SendDataToServer extends AsyncTask<Void,Void,Void> {
private Socket socket;
private String name;
private String password;
private static final String debug = "debug";
private static final String info = "INFO";
protected static String server_IP = "192.168.0.101";
protected static final int server_Port = 8607;

@Override
protected void onPreExecute() {
   Thread thread = new Thread(new Runnable() {
       @Override
       public void run() {
           try {

               Log.i(debug,"Attempt to connect to server");

               socket = new Socket(server_IP,server_Port);
               Log.i(debug,"Connection established");

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

       }
   });
    thread.start();
    }

@Override
protected Void doInBackground(String... data) {

    JSONObject user = new JSONObject();
    try {
        user.put("name", data[0]);
        user.put("name", data[1]);

    } catch (JSONException e) {
        e.printStackTrace();
    }
    try{
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bw.write(String.valueOf(user));
        bw.newLine();
        bw.newLine();
        bw.flush();
        Log.i(info,"JSON has sent");


        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        br.readLine();
        Log.i(info,br.readLine());

    }catch (IOException e) {
        Log.e(debug,"Failed");
    }


    return null;
}

@Override
protected void onPostExecute(Void aVoid) {
    try {
        if(socket!=null){
            socket.close();
        }
    } catch (IOException e) {
        Log.e(debug,"Failed");
    }
 }
}

如您所见,我在doInBackground()方法上进行了一些更改,如果您需要userpassword,则可以按参数将其发送到AsyncTask类,例如:

new SendDataToServer.execute(user,password);

此呼叫应在您的onClickListener()

现在,如果您在这些方法中的代码都能正常工作,它就不会崩溃。

答案 1 :(得分:0)

onPreExecute方法是从主线程调用的。在AsyncTasks内部,所有后台工作都必须在doInBackground方法中编写。我认为在您的情况下,根本不需要重写onPreExecute-只需在doInBackground中转换套接字创建即可:

@Override
protected Void doInBackground(String... credentials) {
JSONObject user = new JSONObject();
try {
    user.put("name", credentials[0]);
    user.put("name", credentials[1]);

} catch (JSONException e) {
    e.printStackTrace();
}
try{
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
    bw.write(String.valueOf(user));
    bw.newLine();
    bw.newLine();
    bw.flush();
    Log.i(info,"JSON has sent");


    BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    br.readLine();
    Log.i(info,br.readLine());

}catch (IOException e) {
    Log.e(debug,"Failed");
}


return null;

}

删除您的构造函数。一定不要自己调用AsyncTask的方法(受监视保护的修饰符,很明显,这样的方法/字段不能被触碰)。如您所见,我将String参数添加到doInBackground中,因此您无需将它们放在构造函数中。现在,您的类声明将如下所示:

class SendDataToServer extends AsyncTask<String,Void,Void> 

后来像这样使用AsyncTask类:

SendDataToServer task = SendDataToServer();
task.execute("custom_name", "custom_login");