2012-08-09 64 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>