2012-08-09 65 views
0

我有一个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 
     } 
} 

在上面的代码如何所以当响应是迟预期不会发生力接近我可以分开的逻辑验证。

我也很感激任何其他更好的方法来解决这种逼近的情况。

+0

thnx jv42为编辑:) – Abhinav 2012-08-09 09:51:16

回答

4

不要包含任何需要时间在主线程中执行的任务。你应该在不同的线程中执行httpCommunication。它会避免这个ANR。

什么文档说>> 在Android中,应用程序响应由Activity Manager和Window Manager系统服务进行监视。 Android会在检测到以下情况之一时显示特定应用程序的ANR对话框: 5秒内未响应输入事件(例如按键,屏幕触摸) BroadcastReceiver尚未在10秒内完成执行

阅读本文档Designing for responsiveness and to avoid ANR

专门创建的,则可以使用AsyncTask为好。

0

使用下面的示例代码来执行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>