-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()またはで呼び出す必要があります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;   
}

ここで、context は使用するアクティビティのコンテキストです。

于 2013-11-06T11:34:16.873 に答える
0

アプリのクラッシュを回避する一般的な方法

Android開発はクラッシュを最も恐れています。テストは問題なく、クラッシュ時にリリースされ、緊急リリースの修正プログラムを介してのみ解決されますが、修正プログラムを準備する時間が非常に長くなる可能性があり、この時間のユーザーエクスペリエンスは非常に貧弱です、Android は Set Thread.setDefaultUncaughtExceptionHandler を渡して例外のすべてのスレッドをキャッチできますが、メイン スレッドが例外をスローすると、アクティビティがフラッシュし、アプリ プロセスが再起動します。ゴキブリを使用すると、異常なアクティビティがフラッシュされなくても、アプリのプロセスが再起動されないことが保証されます。

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

于 2017-02-17T09:09:41.570 に答える