Android Volley - 检查网络状态

26

在使用Volley之前,像往常一样,我使用AsyncTask来检查我的互联网状态。

以下是我在AsyncTask中所做的操作:

private class NetCheck extends AsyncTask<String, Void, Boolean> {

    @Override
    protected Boolean doInBackground(String... args) {
        // get Internet status
        return cd.isConnectingToInternet();
    }

    protected void onPostExecute(Boolean th) {
        if (th == true) {
            new LoadCategories().execute();
        } else {
            Toast.makeText(CategoryActivity.this, "Unable to connect to server",
                    Toast.LENGTH_LONG).show();
        }
    }
}

这是isConnectingToInternet函数:

public boolean isConnectingToInternet() {
    ConnectivityManager connectivity = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivity != null) {
        NetworkInfo info = connectivity.getActiveNetworkInfo();
        if (info != null && info.isConnected())    
            try {
                URL url = new URL("http://www.google.com");
                HttpURLConnection urlc = (HttpURLConnection) url
                        .openConnection();
                urlc.setConnectTimeout(3000);
                urlc.connect();
                if (urlc.getResponseCode() == 200) {
                    return true;
                }
            } catch (MalformedURLException e1) {
                e1.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

    }
    return false;
}

我该如何使用Volley实现这个?

6个回答

112

请求时会抛出NoConnection错误。请在代码中捕获该错误。

   @Override
   public void onErrorResponse(VolleyError volleyError) {
   String message = null;
   if (volleyError instanceof NetworkError) {
         message = "Cannot connect to Internet...Please check your connection!";
   } else if (volleyError instanceof ServerError) {
         message = "The server could not be found. Please try again after some time!!";
   } else if (volleyError instanceof AuthFailureError) {
         message = "Cannot connect to Internet...Please check your connection!";
   } else if (volleyError instanceof ParseError) {
         message = "Parsing error! Please try again after some time!!";
   } else if (volleyError instanceof NoConnectionError) {
         message = "Cannot connect to Internet...Please check your connection!";
   } else if (volleyError instanceof TimeoutError) {
         message = "Connection TimeOut! Please check your internet connection.";
   }
}

12
这并不相同。 NoConnectionError 不仅在没有网络连接时抛出,也会在无法与主机建立连接时抛出(例如,如果无法解析主机名)。 - user2137020
6
既然 NoConnectionError 扩展了 NetworkError,那么你永远不会触发 if (volleyError instanceof NoConnectionError) { - Jon

3

我是如何进行Volley请求并处理响应和错误的,您不需要添加Async任务,因为Volley会在后台进行请求。

StringRequest strReq = new StringRequest(Request.Method.POST, "your_url", new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {

                // handle your response here
                // if your response is a json then create json object and use it
                try {
                    JSONObject jsonObject = new JSONObject(response);

                    // now you can get values from your jsonObject

                }
                catch (Exception e){}

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {

                String message = null; // error message, show it in toast or dialog, whatever you want
                if (volleyError instanceof NetworkError || volleyError instanceof AuthFailureError || volleyError instanceof NoConnectionError || volleyError instanceof TimeoutError) {
                    message = "Cannot connect to Internet";
                } else if (volleyError instanceof ServerError) {
                    message = "The server could not be found. Please try again later";
                }  else if (volleyError instanceof ParseError) {
                    message = "Parsing error! Please try again later";
                }

            }
        }) {
            @Override
            public byte[] getBody() throws AuthFailureError {

                HashMap<String, String> params = new HashMap<>();
                params.put("key","value"); // put your params here

                return new JSONObject(params).toString().getBytes();
            }

            @Override
            public String getBodyContentType() {
                return "application/json";
            }
        };
        // Adding String request to request queue

        Volley.newRequestQueue(getApplicationContext()).add(strReq);

2
我使用以下代码来检测发生了哪个错误:

 new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {


            if (error instanceof TimeoutError || error instanceof NoConnectionError) {
                Toast.makeText(getApplicationContext(), "Communication Error!", Toast.LENGTH_SHORT).show();

            } else if (error instanceof AuthFailureError) {
                Toast.makeText(getApplicationContext(), "Authentication Error!", Toast.LENGTH_SHORT).show();
            } else if (error instanceof ServerError) {
                Toast.makeText(getApplicationContext(), "Server Side Error!", Toast.LENGTH_SHORT).show();
            } else if (error instanceof NetworkError) {
                Toast.makeText(getApplicationContext(), "Network Error!", Toast.LENGTH_SHORT).show();
            } else if (error instanceof ParseError) {
                Toast.makeText(getApplicationContext(), "Parse Error!", Toast.LENGTH_SHORT).show();
            }
        }
    });

1
我设法在Application类中检查互联网。
     public class App extends Application {
            private static final String TAG = "MyApp";

            private static App mInstance;
            private RequestQueue mRequestQueue;
            private ImageLoader mImageLoader;

            public static synchronized App getInstance() {
                return mInstance;
            }

            @Override
            public void onCreate() {
                super.onCreate();
              mInstance = this;
            }

            public RequestQueue getRequestQueue() {
                if (mRequestQueue == null) {
                    mRequestQueue = Volley.newRequestQueue(getApplicationContext());
                }

                return mRequestQueue;
            }



            public <T> void addToRequestQueue(Request<T> req, String tag) {
                // set the default tag if tag is empty
                req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
                getRequestQueue().add(req);
            }

            public <T> void addToRequestQueue(Request<T> req) {

                if(CommonUtills.isNetworkAvailable(getApplicationContext())) {
                    req.setRetryPolicy(new DefaultRetryPolicy(
                            60000,
                            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
                    req.setTag(TAG);
                    getRequestQueue().add(req);
                }
                else
                {
                 Toast.makeText(getApplicationContext(), "Unable to 
connect to server",Toast.LENGTH_LONG).show();
                }
            }

            public void cancelPendingRequests(Object tag) {
                if (mRequestQueue != null) {
                    mRequestQueue.cancelAll(tag);
                }
            }

        }

我会为您进行翻译。以下是需要翻译的内容:

每次我都是使用以下方式调用每个网络请求

App.getInstance().addToRequestQueue(jsonObjRequest);

因此,在调用每个请求之前,如果互联网可用,它将被执行。


1
使用此代码检查互联网状态:

public class Internet {
    private Context context;

    public Internet(Context context) {
        this.context = context;
    }

    public Boolean Check() {
        ConnectivityManager cn = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo nf = cn.getActiveNetworkInfo();
        if (nf != null && nf.isConnected() == true) {
            return true;
        } else {
            Toast.makeText(context, "No internet connection.!",
                    Toast.LENGTH_LONG).show();
            return false;
        }
    }
}

在AndroidManifest.xml中添加权限:<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - Nguyen Thanh An
是的,您可以在启动Asyntask之前使用此代码来检查互联网连接。 - Nguyen Thanh An
但我不想使用AsyncTask。是否可以改用Volley实现? - emen
是的,可以。如果你想从服务器加载图片到列表视图中,你可以使用SmartImageView:http://loopj.com/android-smart-image-view/。 - Nguyen Thanh An
2
嗨,请查看http://arnab.ch/blog/2013/08/asynchronous-http-requests-in-android-using-volley/。希望它能解释清楚你想要做的事情,我认为你可以按照我的回答中提供的方法来操作。我觉得这是一个非常棒和适合的方法。 - Jitesh Upadhyay
@JiteshUpadhyay,当我点击您的链接时,出现文件未找到错误。它在其他地方可用吗?如果您能提供更新的链接,那将非常有帮助。谢谢! - miva2

0
new Response.ErrorListener() {

    @Override
    public void onErrorResponse(VolleyError volleyError) {

        if (volleyError instanceof TimeoutError || volleyError instanceof NoConnectionError) {
            Toast.makeText(getApplicationContext(), "No Connection/Communication Error!", Toast.LENGTH_SHORT).show();

        } else if (volleyError instanceof AuthFailureError) {
            Toast.makeText(getApplicationContext(), "Authentication/ Auth Error!", Toast.LENGTH_SHORT).show();
        } else if (volleyError instanceof ServerError) {
            Toast.makeText(getApplicationContext(), "Server Error!", Toast.LENGTH_SHORT).show();
        } else if (volleyError instanceof NetworkError) {
            Toast.makeText(getApplicationContext(), "Network Error!", Toast.LENGTH_SHORT).show();
        } else if (volleyError instanceof ParseError) {
            Toast.makeText(getApplicationContext(), "Parse Error!", Toast.LENGTH_SHORT).show();
        }
    }
});

这对你作为开发者来说是好事。但不要向最终用户显示一些直接的信息,比如认证和服务器端错误。要有创意,展示一些像“当前无法连接”的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接