与服务器的连接丢失时 Android 应用程序崩溃
在调试 WCF 服务时我遇到了这个问题。我使用 HttpURLConnection
与服务进行通信。在调试服务时,我遇到了一个问题,当 Android 应用程序等待响应时,我必须停止服务器,从而导致 Android 应用程序意外停止。
处理服务器意外突然停止并让 Android 客户端优雅地处理它的最佳方法是什么?我通过 AsyncTask: 堆栈跟踪在后台工作请求/响应
@Override
protected JSONObject doInBackground( BLHttpJSONPostModel ...models) {
JSONObject jsonObject = null;
BLHttpJSONPostModel postModel = models[0];
URL url = null;
byte[] postData = null;
String protocol = null;
String response = null;
InputStream responseStream = null;
OutputStream outStream = null;
HttpURLConnection connection = null;
BufferedReader bufferedReader = null;
StringBuilder builder = null;
try {
url = new URL( postModel.getUrlString() );
postData = postModel.getPostDataAsJsonObject().toString().getBytes();
protocol = url.getProtocol();
} catch (MalformedURLException e1) {
e1.printStackTrace();
return null;
}
if ( protocol.equals("https") ) {
connection = this.setUpHttps( url ); // establishes a secure connection if protocol is HTTPS
}
else if ( protocol.equals("http") ) {
try {
connection = (HttpURLConnection)url.openConnection(); // establishes un-secured connection
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
else
return null; // handles unsupported protocol
try {
connection.setRequestProperty("Content-Length", String.valueOf(postData.length));
connection.setRequestProperty("CONTENT-TYPE", "application/json" );
connection.setRequestMethod( "POST" );
connection.setUseCaches( false );
connection.setDoInput( true );
connection.setDoOutput( true );
connection.connect();
outStream = connection.getOutputStream();
outStream.write(postData);
outStream.close();
String _type = connection.getContentType(); // for debugging only
String _message = connection.getResponseMessage(); // ""
int size = connection.getContentLength(); // ""
bufferedReader = new BufferedReader( new InputStreamReader(connection.getInputStream(), "UTF-8") );
builder = new StringBuilder();
while( (response = bufferedReader.readLine()) != null ) {
builder.append(response);
}
} catch (IOException e) {
e.printStackTrace(); // no exceptio caught here
} finally {
connection.disconnect();
}
if ( (builder != null) && (! builder.toString().equals("")) ) {
try {
jsonObject = new JSONObject( builder.toString() );
} catch (JSONException e) {
e.printStackTrace();
}
}
return jsonObject;
}
:
02-20 12:13:33.935: E/AndroidRuntime(1173): FATAL EXCEPTION: AsyncTask #1
02-20 12:13:33.935: E/AndroidRuntime(1173): java.lang.RuntimeException: An error occured while executing doInBackground()
02-20 12:13:33.935: E/AndroidRuntime(1173): at android.os.AsyncTask$3.done(AsyncTask.java:200)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.lang.Thread.run(Thread.java:1096)
02-20 12:13:33.935: E/AndroidRuntime(1173): Caused by: java.lang.NullPointerException
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.io.Reader.<init>(Reader.java:65)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.io.InputStreamReader.<init>(InputStreamReader.java:93)
02-20 12:13:33.935: E/AndroidRuntime(1173): at com.beslogic.remotpayment.connection.PostJSONTask.doInBackground(PostJSONTask.java:136)
02-20 12:13:33.935: E/AndroidRuntime(1173): at com.beslogic.remotpayment.connection.PostJSONTask.doInBackground(PostJSONTask.java:1)
02-20 12:13:33.935: E/AndroidRuntime(1173): at android.os.AsyncTask$2.call(AsyncTask.java:185)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-20 12:13:33.935: E/AndroidRuntime(1173): ... 4 more
While debugging a WCF service I came across this issue. I use an HttpURLConnection
communicate with the service. While debugging the service, I came across an issue where I had to stop the server while the Android application was waiting for a response, causing the Android application to stop unexpectedly.
What would the best method to deal with a server unexpectedly suddenly stopping and having the android client deal with it gracefully. I have the request/respone working in the background via an AsyncTask:
@Override
protected JSONObject doInBackground( BLHttpJSONPostModel ...models) {
JSONObject jsonObject = null;
BLHttpJSONPostModel postModel = models[0];
URL url = null;
byte[] postData = null;
String protocol = null;
String response = null;
InputStream responseStream = null;
OutputStream outStream = null;
HttpURLConnection connection = null;
BufferedReader bufferedReader = null;
StringBuilder builder = null;
try {
url = new URL( postModel.getUrlString() );
postData = postModel.getPostDataAsJsonObject().toString().getBytes();
protocol = url.getProtocol();
} catch (MalformedURLException e1) {
e1.printStackTrace();
return null;
}
if ( protocol.equals("https") ) {
connection = this.setUpHttps( url ); // establishes a secure connection if protocol is HTTPS
}
else if ( protocol.equals("http") ) {
try {
connection = (HttpURLConnection)url.openConnection(); // establishes un-secured connection
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
else
return null; // handles unsupported protocol
try {
connection.setRequestProperty("Content-Length", String.valueOf(postData.length));
connection.setRequestProperty("CONTENT-TYPE", "application/json" );
connection.setRequestMethod( "POST" );
connection.setUseCaches( false );
connection.setDoInput( true );
connection.setDoOutput( true );
connection.connect();
outStream = connection.getOutputStream();
outStream.write(postData);
outStream.close();
String _type = connection.getContentType(); // for debugging only
String _message = connection.getResponseMessage(); // ""
int size = connection.getContentLength(); // ""
bufferedReader = new BufferedReader( new InputStreamReader(connection.getInputStream(), "UTF-8") );
builder = new StringBuilder();
while( (response = bufferedReader.readLine()) != null ) {
builder.append(response);
}
} catch (IOException e) {
e.printStackTrace(); // no exceptio caught here
} finally {
connection.disconnect();
}
if ( (builder != null) && (! builder.toString().equals("")) ) {
try {
jsonObject = new JSONObject( builder.toString() );
} catch (JSONException e) {
e.printStackTrace();
}
}
return jsonObject;
}
Stack trace:
02-20 12:13:33.935: E/AndroidRuntime(1173): FATAL EXCEPTION: AsyncTask #1
02-20 12:13:33.935: E/AndroidRuntime(1173): java.lang.RuntimeException: An error occured while executing doInBackground()
02-20 12:13:33.935: E/AndroidRuntime(1173): at android.os.AsyncTask$3.done(AsyncTask.java:200)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.lang.Thread.run(Thread.java:1096)
02-20 12:13:33.935: E/AndroidRuntime(1173): Caused by: java.lang.NullPointerException
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.io.Reader.<init>(Reader.java:65)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.io.InputStreamReader.<init>(InputStreamReader.java:93)
02-20 12:13:33.935: E/AndroidRuntime(1173): at com.beslogic.remotpayment.connection.PostJSONTask.doInBackground(PostJSONTask.java:136)
02-20 12:13:33.935: E/AndroidRuntime(1173): at com.beslogic.remotpayment.connection.PostJSONTask.doInBackground(PostJSONTask.java:1)
02-20 12:13:33.935: E/AndroidRuntime(1173): at android.os.AsyncTask$2.call(AsyncTask.java:185)
02-20 12:13:33.935: E/AndroidRuntime(1173): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-20 12:13:33.935: E/AndroidRuntime(1173): ... 4 more
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我经常遇到这个问题。问题(由于某种原因)是您捕获的 Exception 对象
e
可能为 null。在 try catch 语句中,执行以下操作:对两个
try ... catch
块执行此操作。我知道我现在的解决方案听起来很荒谬,但我经常遇到这种情况,足以假设您可能面临同样的问题。I have faced this problem way too often. The problem (for some reason) is that the Exception object
e
that you are catching could be null. In your try catch statement, do this:Do it for both the
try ... catch
blocks. I know my solution right now sounds ridiculous, but I have faced this often enough to assume that you might be facing the same issue.答案要简单得多(通常如此)。
在实例化
BufferedReader
的地方,由于连接已断开,connection.getInputStream()
返回 null。应该是:
这引发了一个未被捕获的运行时异常。
The answer was a lot simpler (as it usually is).
Where the
BufferedReader
is instantiated, since the connection was broken,connection.getInputStream()
was returning null.It should be:
This was throwing a run time exception that was not being caught.