java - 当我尝试发送 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");
}
}
}
我真的很想知道这个问题是什么以及如何解决它。感谢帮助。
解决方案
我建议您阅读AsyncTask-Android-Example 的一些答案。
然后你需要知道像这样的方法:
- onPreExecute();
- 做背景();
- 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()
方法上进行了一些更改,如果需要user
,password
您可以通过参数将其发送到AsyncTask
类,如下所示:
new SendDataToServer.execute(user,password);
这个电话应该在你的onClickListener()
现在,如果您在这些方法中的代码有效,它应该不会崩溃。
推荐阅读
- python - python将元组值插入mysql数据库
- scala - Play Framework 2.4.1 一个带有两个按钮的表单。按下了哪个按钮?以及如何获取输入数据?
- ruby-on-rails - 在 Ruby 中编译资产是否需要在部署中完成?为什么不是以前?
- c# - 有没有办法对列表中的对象进行分组?
- c - 如何在 C 中最小化动态分配的字符串数组?
- prestashop - PrestaShop 邮件警报模块设置
- java - while循环没有从java中的docker事件中的bufferedReader中断
- c# - 我需要一个 C# 中的过滤程序
- tabs - 选项卡在 dm-script 的对话框中不起作用
- javascript - 如何使用 Firebase 对过滤后的结果进行分页?