首页 > 解决方案 > 当我尝试发送 json 时,我的套接字出现 NullPointerException

问题描述

我正在制作一个服务器客户端项目,当我尝试发送 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");
    }
 }
}

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

标签: javaandroid

解决方案


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

然后你需要知道像这样的方法:

  1. onPreExecute();
  2. 做背景();
  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()

现在,如果您在这些方法中的代码有效,它应该不会崩溃。


推荐阅读