Android-如何避免因网络丢失导致的应用崩溃

时间:2013-11-06 11:29:00

标签: android

我有一个聊天应用,试图将某人签到服务器。登录的代码使用AsyncTask实现。问题是在登录过程中并且存在网络丢失,尽管我使用了所有try ... catch语句,但应用程序崩溃了。请问如何通过告知用户网络丢失而不是应用程序崩溃来优雅地处理此问题。

我在调用asynctask之前检查了网络,但我想避免的是当你处于进程的中间并且网络突然丢失时

这是代码的一部分

protected String doInBackground(String... args) {
        try {

        DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(LOGIN_URL);
                httpPost.setEntity(new UrlEncodedFormEntity(params));

                HttpResponse httpResponse = httpClient.execute(httpPost);

                int statusCode=httpResponse.getStatusLine().getStatusCode();

                if(statusCode!=HttpStatus.SC_OK){

                    Log.d("latestchat", "Connection Error");

                    Toast.makeText(Login.this, "Error in Network Connection\n ", Toast.LENGTH_LONG).show();
                    return null;
                }

                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();


          if(is!=null){
       BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            // Declare a string builder to help with the parsing.
            StringBuilder sb = new StringBuilder();
            // Declare a string to store the JSON object data in string form.
            String line = null;

            // Build the string until null.
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }

            // Close the input stream.
            is.close();
            // Convert the string builder data to an actual string.
            json = sb.toString();
            jObj = new JSONObject(json);


          }

        } catch (JSONException e) {
            Log.d("latestchat", "JSon error: "+e.toString());

            Toast.makeText(Login.this, "Error in Network Connection\n "+e.getMessage(), Toast.LENGTH_LONG).show();

        }
        catch (UnsupportedEncodingException e) {
            Toast.makeText(Login.this, "Unsupported Encoding ", Toast.LENGTH_LONG).show();
        } catch (ClientProtocolException e) {
            Toast.makeText(Login.this, "Protocol not supported ", Toast.LENGTH_LONG).show();

        } catch (IOException e) {
            Toast.makeText(Login.this, "Error connecting to Server ", Toast.LENGTH_LONG).show();
            Log.e("latestchat", "Error connecting to Server " + e.toString());

        }
        catch (Exception e) {
            Toast.makeText(Login.this, "Error connecting to Server ", Toast.LENGTH_LONG).show();
            Log.e("latestchat", "Error connecting to Server " + e.toString());

        }
        return null;

    }

这是logcat

11-06 13:03:17.169 E/AndroidRuntime(16149):     at com.example.latestchat.Login$AttemptLogin.doInBackground(Login.java:303)
11-06 13:03:17.169 E/AndroidRuntime(16149):     at com.example.latestchat.Login$AttemptLogin.doInBackground(Login.java:1)
11-06 13:05:58.249 E/AndroidRuntime(16405):     at com.example.latestchat.Login$AttemptLogin.doInBackground(Login.java:303)
11-06 13:05:58.249 E/AndroidRuntime(16405):     at com.example.latestchat.Login$AttemptLogin.doInBackground(Login.java:1)
11-06 13:05:59.329 E/WindowManager(16405): Activity com.example.latestchat.Login has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@407cb440 that was originally added here
11-06 13:05:59.329 E/WindowManager(16405): android.view.WindowLeaked: Activity com.example.latestchat.Login has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@407cb440 that was originally added here
11-06 13:05:59.329 E/WindowManager(16405):  at com.example.latestchat.Login$AttemptLogin.onPreExecute(Login.java:186)
11-06 13:05:59.329 E/WindowManager(16405):  at com.example.latestchat.Login.newLogin(Login.java:171)
11-06 13:05:59.329 E/WindowManager(16405):  at com.example.latestchat.Login.logIn(Login.java:120)
11-06 13:07:20.429 E/AndroidRuntime(16573):     at com.example.latestchat.Login$AttemptLogin.doInBackground(Login.java:303)
11-06 13:07:20.429 E/AndroidRuntime(16573):     at com.example.latestchat.Login$AttemptLogin.doInBackground(Login.java:1)
11-06 13:07:21.119 E/WindowManager(16573): Activity com.example.latestchat.Login has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@407c9468 that was originally added here
11-06 13:07:21.119 E/WindowManager(16573): android.view.WindowLeaked: Activity com.example.latestchat.Login has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@407c9468 that was originally added here
11-06 13:07:21.119 E/WindowManager(16573):  at com.example.latestchat.Login$AttemptLogin.onPreExecute(Login.java:186)
11-06 13:07:21.119 E/WindowManager(16573):  at com.example.latestchat.Login.newLogin(Login.java:171)
11-06 13:07:21.119 E/WindowManager(16573):  at com.example.latestchat.Login.logIn(Login.java:120)

5 个答案:

答案 0 :(得分:3)

您正在Toast.makeText()内进行用户界面操作(doInBackground())。这是错误的,因为执行doInBackground()的线程不是主(UI)线程。

应在Toast.makeText()onPostExecute()中调用

onCancelled()。请重新编写代码以实现此目的。

我的建议是,如果发现网络异常,则在cancel()内执行doInBackground(),因此onCancelled()将被调用,而不是onPostExecute(),然后执行{{1}在Toast.makeText()内。

答案 1 :(得分:1)

您可以先检查网络是否可用。这是我在某些应用中使用的方法:

public boolean isNetworkAvailable() {
    return  isNetworkAvailable(false);
}

public boolean isNetworkAvailable(boolean withToast) {
        ConnectivityManager connectivityManager = (ConnectivityManager) this
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager
                .getActiveNetworkInfo();
        if (activeNetworkInfo == null) {
            if (withToast) {
                Toast.makeText(getApplicationContext(),
                        R.string.checkYourConnexion, Toast.LENGTH_LONG).show();
            }
            return false;
        } else
            return activeNetworkInfo.isConnectedOrConnecting();
    }

答案 2 :(得分:0)

在执行Web服务请求之前,您需要检查网络是否可用。

如果在w / s请求后网络丢失,您应该捕获超时异常并向用户显示相应的消息。

答案 3 :(得分:0)

在拨打电话之前,请使用以下功能,无论是否存在网络连接。

private boolean isNetworkConnected(Context context)
{
    ConnectivityManager connectivityManager =     (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null;   
}

此处,上下文是您将使用的活动上下文。

答案 4 :(得分:0)

避免应用崩溃的常用方法

Android开发最怕崩溃,测试没问题,在崩溃时发布,只能通过紧急发布修补程序来解决,但是编写修补程序的时间可能会很长,导致此时的用户体验非常差,android可以通过Set Thread.setDefaultUncaughtExceptionHandler来捕获异常的所有线程,但主线程抛出异常仍会导致活动闪烁,app进程重启。使用Cockroach可以保证无论异常活动如何不闪现,app进程都不会重启。

https://github.com/android-notes/Cockroach/blob/master/README_en.md