【问题标题】:How to handle 'force close' due late response time from server由于服务器响应时间延迟,如何处理“强制关闭”
【发布时间】:2023-03-23 05:17:01
【问题描述】:

我有一个 android 应用程序,其中有许多请求和响应发生在来自服务器的场景。例如:loginauthentication。当用户输入usernamepassword 时,凭据将根据服务器响应的凭据进行验证。

但有时会出现由于网络慢导致响应迟到,android弹出强制关闭对话框,非常尴尬。

我在想有没有一种方法可以将到达服务器的代码隔离在某个单独的线程中,直到它得到我的响应。我可能会显示进度条而不是强制关闭。这是一个好的解决方案吗?

示例代码:

//this code will be called when user presses Login button on UI
public void authenticate(View view) {
      //the logic for authentication
      if(authentication==true){
         //go to home page
        }
}

在上面的代码中,如何分离身份验证逻辑,以便在响应按预期延迟时不会发生强制关闭。

我也希望有任何其他更好的方法来解决这种强制关闭的情况。

【问题讨论】:

    标签: android multithreading android-activity forceclose


    【解决方案1】:

    不要在主线程中包含任何需要时间执行的任务。您应该在不同的线程中执行 httpCommunication。它将避免此 ANR。

    文档是怎么说的>> 在 Android 中,应用程序的响应由活动管理器和窗口管理器系统服务监控。当检测到以下情况之一时,Android 将显示特定应用程序的 ANR 对话框: 5 秒内无响应输入事件(例如按键、屏幕触摸) BroadcastReceiver 没有在 10 秒内完成执行

    阅读这份专为Designing for responsiveness and to avoid ANR创建的文档

    您也可以使用AsyncTask

    【讨论】:

      【解决方案2】:

      您可以使用AsyncTaskhttp://loopj.com/android-async-http/

      同时在 UI 上显示进度对话框。提供一个回调函数,一旦收到来自服务器的响应就会被调用。

      【讨论】:

        【解决方案3】:

        使用下面的示例代码执行login 进程。您可以使用AsyncTask 进行登录过程。

        LoginActivity 类,它使用AsyncTask

        • 点击Login按钮,我是executingAsyncTask
        • 在登录过程中,这将显示ProgressDialog
        • 流程完成后,关闭ProgressDialog并向用户显示状态消息

        类代码:

        import android.app.Activity;
        import android.app.AlertDialog;
        import android.app.ProgressDialog;
        import android.content.DialogInterface;
        import android.os.AsyncTask;
        import android.os.Bundle;
        import android.view.View;
        import android.view.View.OnClickListener;
        import android.widget.Button;
        import android.widget.EditText;
        import android.widget.Toast;
        
        public class LoginActivity extends Activity {
        
            private Button login_Button = null;
            private EditText userNameText = null;
            private EditText passwordText = null;
            private String uName = "";
            private String pass = "";
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.test_login);
                login_Button = (Button) findViewById(R.id.cmdDoLogin);
        
                userNameText = (EditText) findViewById(R.id.editTextUserName);
                passwordText = (EditText) findViewById(R.id.editTextPassword);
        
                login_Button.setOnClickListener(new OnClickListener() {
        
                    public void onClick(View paramView) {
                        uName = userNameText.getText().toString().trim();
                        pass = passwordText.getText().toString().trim();
                        if (uName.equals("") || pass.equals("")) {
                            Toast.makeText(LoginActivity.this,
                                    "Fill both username and password fields",
                                    Toast.LENGTH_SHORT).show();
        
                        } else {
                            new LoginActivity.DoLoginProcess().execute(); // calling the AsyncTask here
                        }
                    }
                });
        
            }
        
            private class DoLoginProcess extends AsyncTask<Void, Void, Integer> {
        
                ProgressDialog pd = null;
        
                @Override
                protected void onPreExecute() {
                    super.onPreExecute();
                    pd = new ProgressDialog(LoginActivity.this);
                    pd.setTitle("Logging In...");
                    pd.setMessage("Please wait...");
                    pd.setCancelable(false);
                    pd.show();
        
                }
        
                @Override
                protected Integer doInBackground(Void... params) {
                    int loginStatus = 0 ; // treat this as loginStatus. 0 = login failed; 1=login success. You can return this value to onPostExecute function
        
                    //*********************************************
                    // do login process over internet here. Hope you already have the code to do the login process over internet.
                    //*********************************************         
        
                    return loginStatus;
                }
        
                @Override
                protected void onPostExecute(Integer status) {
                    super.onPostExecute(status);
                    pd.dismiss(); // dismiss the progress dialog
        
                    if (status == 0) { // login failed
                        AlertDialog alertDialog = new AlertDialog.Builder(
                                LoginActivity.this).create();
                        alertDialog.setTitle("Error");
                        alertDialog.setMessage("Login failed");
                        alertDialog.setButton("OK",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog,
                                            int which) {
                                        LoginActivity.this.finish();
                                        dialog.cancel();
                                    }
                                });
                        alertDialog.setIcon(android.R.drawable.ic_dialog_info);
                        alertDialog.show();
                    } else if(status == 1) { // login success
                        AlertDialog alertDialog = new AlertDialog.Builder(
                                LoginActivity.this).create();
                        alertDialog.setTitle("Success");
                        alertDialog.setMessage("Login success");
                        alertDialog.setButton("OK",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog,
                                            int which) {
                                        LoginActivity.this.finish();
                                        dialog.cancel();
                                    }
                                });
                        alertDialog.setIcon(android.R.drawable.ic_dialog_info);
                        alertDialog.show();
                    }
                }
            }
        
        
        }
        

        test_login 布局 XML 文件:

        <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/loginbglayout"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:padding="10dp" >
        
            <TableLayout
                android:id="@+id/holderLayout"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true" >
        
                <TableRow
                    android:id="@+id/row1"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center" >
        
                    <TextView
                        android:id="@+id/textViewUserName"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginRight="10dp"
                        android:gravity="right"
                        android:text="UserName"
                        android:textColor="#ffffff" />
        
                    <EditText
                        android:id="@+id/editTextUserName"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_weight="1" >
                    </EditText>
                </TableRow>
        
                <TableRow
                    android:id="@+id/row2"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:gravity="center" >
        
                    <TextView
                        android:id="@+id/textView2"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginRight="10dp"
                        android:gravity="right"
                        android:text="Password"
                        android:textColor="#ffffff" />
        
                    <EditText
                        android:id="@+id/editTextPassword"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:inputType="textPassword" />
                </TableRow>
        
                <TableRow
                    android:id="@+id/row3"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:gravity="center" >
        
                    <View
                        android:layout_width="0dp"
                        android:layout_height="2dip"
                        android:layout_weight="1"
                        android:focusable="false" />
        
                    <Button
                        android:id="@+id/cmdDoLogin"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="right"
                        android:text="Login" >
                    </Button>
                </TableRow>
            </TableLayout>
        
        </RelativeLayout>
        

        【讨论】:

          猜你喜欢
          • 2012-02-08
          • 1970-01-01
          • 2018-05-19
          • 2016-10-09
          • 2011-09-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多