-3

我有一个聊天应用程序,它试图让某人登录到服务器。登录代码是使用 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;

    }

这是日志猫

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)
4

5 回答 5

3

您正在执行一个 UI 操作 ( Toast.makeText()) 里面doInBackground()。这是错误的,因为执行的线程doInBackground()不是主 (UI) 线程。

Toast.makeText()应该在onPostExecute()or中调用onCancelled()。请重新编写您的代码以完成此操作。

我的建议是如果捕获到网络异常就在cancel()内部执行,因此将调用 next 而不是,然后在内部执行。doInBackground()onCancelled()onPostExecute()Toast.makeText()onCancelled()

于 2013-11-06T12:30:21.477 回答
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();
    }
于 2013-11-06T11:35:06.143 回答
0

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

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

于 2013-11-06T11:33:31.390 回答
0

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

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

在这里,上下文是您将使用的活动上下文。

于 2013-11-06T11:34:16.873 回答
0

避免应用程序崩溃的常用方法

Android开发最怕crash,测试没问题,发布就crash,只能通过紧急发布hotfix来解决,但是准备hotfix的时间可能会很长,导致这个时候用户体验很差,android可以通过Set Thread.setDefaultUncaughtExceptionHandler来捕获所有线程的异常,但是主线程抛出异常仍然会导致activity闪烁,app进程重启。使用 Cockroach 可以保证无论活动如何异常都不会闪烁,app 进程也不会重启。

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

于 2017-02-17T09:09:41.570 回答