我发送请求json到服务器并使用Asyntask接收它,我在doInBackground中执行httppost,如下所示:
HttpResponse httpResponse = httpClient.execute(httpPost);
如果我在等待服务器响应时禁用互联网连接,应用程序将崩溃!问题是我不知道如何处理这个异常(RuntimeException) 并且我在我的应用程序中处理这些异常:
ConnectionTimeoutException,SocketTimeoutException,NetworkOnMainThreadException,IllegalStateException,IOException, UnsupportedEncodingException,ClientProtocolException
public class GetJSON extends AsyncTask<String, Void, String> {
String username;
String password;
Context context;
ArrayList<NameValuePair> valuesForServer =new ArrayList<NameValuePair>();
InputStream inputStream = null;
String result = "";
public GetJSON(Context context,String username, String password){
this.username=username;
this.password=password;
this.context=context;
valuesForServer.add(new BasicNameValuePair("api_key", "teroapi_php_java_1395"));
valuesForServer.add(new BasicNameValuePair("api_function", "login"));
valuesForServer.add(new BasicNameValuePair("username",this.username));
valuesForServer.add(new BasicNameValuePair("password",this.password));
}
@Override
protected String doInBackground(String... urls) {
try {
String url=urls[0];
// Set up HTTP post
// HttpClient is more then less deprecated. Need to change to URLConnection
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 10000);
HttpConnectionParams.setSoTimeout(httpParameters, 10000);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(valuesForServer));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
StatusLine statusLine = httpResponse.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
// Read content & Log
inputStream = httpEntity.getContent();
}else{
return null;
}
}catch(ConnectTimeoutException e5){
Toast.makeText(this.context, e5 + "", Toast.LENGTH_SHORT).show();
e5.printStackTrace();
return null;
}catch (NetworkOnMainThreadException e7){
Toast.makeText(this.context, e7 + "", Toast.LENGTH_SHORT).show();
e7.printStackTrace();
return null;
} catch(SocketTimeoutException e6){
Toast.makeText(this.context, e6 + "", Toast.LENGTH_SHORT).show();
e6.printStackTrace();
return null;
} catch (UnsupportedEncodingException e1) {
Toast.makeText(this.context, e1 + "", Toast.LENGTH_SHORT).show();
e1.printStackTrace();
return null;
} catch (ClientProtocolException e2) {
Toast.makeText(this.context,e2+"",Toast.LENGTH_SHORT).show();
e2.printStackTrace();
return null;
} catch (IllegalStateException e3) {
Toast.makeText(this.context,e3+"",Toast.LENGTH_SHORT).show();
e3.printStackTrace();
return null;
} catch (IOException e4) {
Toast.makeText(this.context,e4+"",Toast.LENGTH_SHORT).show();
e4.printStackTrace();
return null;
}
// Convert response to string using String Builder
if(inputStream!=null) {
try {
BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"), 8);
StringBuilder sBuilder = new StringBuilder();
String line = null;
while ((line = bReader.readLine()) != null) {
sBuilder.append(line + "\n");
}
inputStream.close();
result = sBuilder.toString();
} catch (Exception e) {
Toast.makeText(this.context, e + "", Toast.LENGTH_SHORT).show();
return null;
}
}else {
return null;
}
return result;
}
@Override
public void onPostExecute(String result) {
if (result != null) {
MainActivity.analizeData(result);
if (MainActivity.success.equals("1")) {
MainActivity.teamsFragment.parseJSON();
MainActivity.projectsFragment.parseJSON();
MainActivity.dutiesFragment.parseJSON();
insertToDb(result);
try {
Picasso.with(context)
.load("http://teroject.com/upload/avatars/" + MainActivity.information.getString("profilepicurl") + ".jpg")
.error(R.drawable.avatar)
.into(MainActivity.navProfilePic);
} catch (JSONException e) {
Toast.makeText(this.context,e+"",Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
} else if (MainActivity.success.equals("0")) {
Intent intent = new Intent(context, LoginActivity.class);
context.startActivity(intent);
Toast.makeText(context, "لطفا مجددا وارد شوید",
Toast.LENGTH_LONG).show();
((Activity) context).overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
((Activity) context).finish();
SharedPreferences sharedPreferences = context.getSharedPreferences(TeroSession.TEROPREFS, context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.clear();
editor.apply();
deleteFromDb();
}
}else {
Toast.makeText(this.context,"مشکلی در برقراری ارتباط بوجود آمده \n" +
"لطفا مجددا تلاش کنید",Toast.LENGTH_LONG).show();
}
}
}
我的logcat:
07-24 02:52:27.591 3601-3723/com.teroject.teroject E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.teroject.teroject, PID: 3601
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.widget.Toast$TN.<init>(Toast.java:353)
at android.widget.Toast.<init>(Toast.java:108)
at android.widget.Toast.makeText(Toast.java:267)
at com.teroject.teroject.GetJSON.doInBackground(GetJSON.java:116)
at com.teroject.teroject.GetJSON.doInBackground(GetJSON.java:48)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
非常感谢您抽出宝贵的时间!
答案 0 :(得分:1)
这基本上意味着你不能从后台线程中创建Toasts
(或进行任何其他UI修改),而是UI线程。有两种方法可以解决这个问题:
将每个Toast
转换为Log.i("some tag", e + "")
,因为您正在使用Toasts来捕获错误,Log
是一种更好的方法。这些日志将显示在您的Android监视器中(您可以使用CTRL+F
进行搜索)
您也可以使用Activity.runOnUiThread()
并以这种方式发布Toasts
,这是一个更糟糕的选择,因为您并不真正需要它们,您只是使用它们进行调试。