0

I am making a server-client project and something is wrong with my client-side when I am trying to send JSON file. Server - side is ok and works as well. Errors in Logcat say that my problem in buffered reader. Sry for my English, am only student_).

Errors

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)

My client-using AsyncTask(this name and password i get from editName.getText.toString and password the same

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");
    }
 }
}

I really want to know what is this problem and how to solve it. Thanks for help.

Creator -3000
  • 71
  • 1
  • 12

2 Answers2

0

I recomend you to read some answers from AsyncTask-Android-Example.

Then you need to know that the methods like :

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

Are called autommatically.

So you should change your code to this :

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");
    }
 }
}

As you can see I've changed something on doInBackground() method, if you need user and password you can send it to the AsyncTask class by parameter, like this :

new SendDataToServer.execute(user,password);

This call should be on your onClickListener()

Now if your code inside of those methods works, it should not crash.

Skizo-ozᴉʞS
  • 16,233
  • 16
  • 66
  • 129
  • Really thanks, this one helped me. But what i should do with this? `BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bw.write(user); bw.newLine(); bw.flush();` I don`t know how to send it exactly to json because my server will be responsible only for json format. – Creator -3000 Sep 09 '18 at 22:16
  • I do not know what it does... – Skizo-ozᴉʞS Sep 09 '18 at 22:17
  • i have edited, hope u would understand. Error is cannot resolve to org.json – Creator -3000 Sep 09 '18 at 22:20
  • @Creator-3000 I think this is another question... your main question was what's wrong on this AsyncTask class, now you know, then understand what happens on BufferedWriter is another question, feel free to ask and send me the link, maybe tomorrow I can take a look. – Skizo-ozᴉʞS Sep 09 '18 at 22:22
0

onPreExecute method is called from the main thread. Inside AsyncTasks all background work must be written inside doInBackground method. I think in your case there is no need to override onPreExecute at all - just transform socket creation inro 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;

}

Delete your constructor. Methods of AsyncTask must not be called by yourself (watch protected modifier, it's quite clear sign that such methods/fields shoul not be touched). As you can see I added String parameters to the doInBackground so you don't need put them in constructor. Now your class declaration will look like that:

class SendDataToServer extends AsyncTask<String,Void,Void> 

Later use AsyncTask class like that:

SendDataToServer task = SendDataToServer();
task.execute("custom_name", "custom_login");
AlexF
  • 307
  • 3
  • 16