我正在做一个服务器-客户端项目,当我尝试发送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");
}
}
}
我真的很想知道这个问题是什么以及如何解决。感谢帮助。
答案 0 :(得分:0)
我建议您阅读AsyncTask-Android-Example的一些答案。
然后,您需要知道类似的方法:
被自动调用。
所以您应该将代码更改为此:
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()
现在,如果您在这些方法中的代码都能正常工作,它就不会崩溃。
答案 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");