0

我正在创建一个应用程序,当您使用用户名和密码登录时,它会向服务器请求信息。 服务器的请求需要一定的时间(15-20秒),同时我想显示一个单词很少的旋转栏。 但我尝试了AsyncTask这个类的很多变体,我无法让它工作。它得到的信息没问题,但冻结屏幕直到响应。 现在我只是有一个新线程实施runnable。我不知道从代码的哪个位置我需要拨打AsyncTaskAsyncTask进程

onClick触发attemptLogin()功能:

public void onClick(View view) { 
     attemptLogin(); 
    } 

attemptLogin()功能:

// more code 
showProgress(true); 
new Thread(new GetServerResponseRunnable()).start(); 
while (wait) {} 
// more code 

而且Runnable的是:

public class GetServerResponseRunnable implements Runnable { 
    @Override 
    public void run() { 
     response = getInfo.getTours(mUsername, mPassword); 
     wait = false; 
    }  

} 

正如你可以看到从调用另一个函数一个不同的班级。 这是函数:

public String getTours(String username, String password) { 
    String req = "GETALLDATA"; 
    String retStr = ""; 
    try { 
     url = getURL(req, username, password); 
     sendOutputLine(url, ""); 
     retStr = getReturnString(); 
     Log.d(LoginActivity.DEBUG_TAG, "getTours() return: " + retStr); 
    } catch (Exception e) { 
     Log.d(LoginActivity.DEBUG_TAG, "programm bommed client: " + e.getMessage()); 
    } 
    return retStr; 
} 

我需要帮助,请。主要是我想要做的是:

response = getInfo.getTours(mUsername, mPassword); 
    wait = false; 

而同时显示旋转酒吧。

感谢


更新:2013年2月13日

我用这个代码,但我得到了

02-13 09:07:16.142: E/AndroidRuntime(1046): java.lang.NullPointerException 
在该行

this.dialog.setMessage(getResources().getString(R.string.login_progress_signing_in)); 

任何想法为什么?

public class LoginTask extends AsyncTask<Object, Void, String> { 

    public Context context; 
    public ProgressDialog dialog; 


    public void BaseTask(Context context) { 
     this.context = context; 
     this.dialog = new ProgressDialog(context); 
    } 

    @Override 
    protected void onPreExecute() { 
     this.dialog.setMessage(getResources().getString(R.string.login_progress_signing_in)); 
     this.dialog.show(); 

    } 

    @Override 
    protected String doInBackground(Object... objects) { 
     String name = (String) objects[0]; 
     String password = (String) objects[1]; 
     String response = getInfo.getTours(name , password); 
     return response; 
    } 

    @Override 
    protected void onPostExecute(String response) { 
     if (dialog != null && dialog.isShowing()) 
      dialog.dismiss(); 

     LoginActivity.response = response; 

     // process response as you need 
    } 
} 

回答

1

我认为你需要thomething这样

public class LoginTask extends AsyncTask<Object, Void, String> { 

    public Context context; 
    public ProgressDialog dialog; 


    public BaseTask(Context context) { 
     this.context = context; 
     this.dialog = new ProgressDialog(context); 
    } 

    @Override 
    protected void onPreExecute() { 
     this.dialog.setMessage(context.getResources().getString(R.string.loading)); 
     this.dialog.show(); 

    } 

    @Override 
    protected String doInBackground(Object... objects) { 
     String name = (String) objects[0]; 
     String password = (String) objects[1]; 
     String response = getInfo.getTours(name , password); 
     return response; 
    } 

    @Override 
    protected void onPostExecute(String response) { 
     if (dialog != null && dialog.isShowing()) 
      dialog.dismiss(); 

     // process response as you need 
    } 
} 

调用此TAKS

public void onClick(View view) { 
    new LoginTask(YourActivity.this).execute(name, password); 
} 
+0

谢谢,但我该怎么称呼这个班?只是创建它的新实例?我如何传递用户名和密码? – Mike 2013-02-12 22:55:23

+0

更新了我的答案,有关更多详细信息,请参阅http://developer.android.com/reference/android/os/AsyncTask.html – 2013-02-13 06:24:45

+0

我更新了代码,您可以查看一下吗?我正在从'attemptLogin()'中调用新的LoginTask。可以吗?或者我需要从onClick? – Mike 2013-02-13 14:10:42

0

尝试实施android登录活动。 在下面创建新的活动你的ADT挑:登录活动 这将产生以下模板代码为您:

/** 
* Activity which displays a login screen to the user, offering registration as 
* well. 
*/ 
public class LoginActivityTest extends Activity { 
    /** 
    * A dummy authentication store containing known user names and passwords. 
    * TODO: remove after connecting to a real authentication system. 
    */ 
    private static final String[] DUMMY_CREDENTIALS = new String[] { 
      "[email protected]:hello", "[email protected]:world" }; 

    /** 

     * The default email to populate the email field with. 
     */ 
     public static final String EXTRA_EMAIL = "com.example.android.authenticatordemo.extra.EMAIL"; 

     /** 
     * Keep track of the login task to ensure we can cancel it if requested. 
     */ 
     private UserLoginTask mAuthTask = null; 

     // Values for email and password at the time of the login attempt. 
     private String mEmail; 
     private String mPassword; 

     // UI references. 
     private EditText mEmailView; 
     private EditText mPasswordView; 
     private View mLoginFormView; 
     private View mLoginStatusView; 
     private TextView mLoginStatusMessageView; 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      setContentView(R.layout.activity_login_activity_test); 

      // Set up the login form. 
      mEmail = getIntent().getStringExtra(EXTRA_EMAIL); 
      mEmailView = (EditText) findViewById(R.id.email); 
      mEmailView.setText(mEmail); 

      mPasswordView = (EditText) findViewById(R.id.password); 
      mPasswordView 
        .setOnEditorActionListener(new TextView.OnEditorActionListener() { 
         @Override 
         public boolean onEditorAction(TextView textView, int id, 
           KeyEvent keyEvent) { 
          if (id == R.id.login || id == EditorInfo.IME_NULL) { 
           attemptLogin(); 
           return true; 
          } 
          return false; 
         } 
        }); 

      mLoginFormView = findViewById(R.id.login_form); 
      mLoginStatusView = findViewById(R.id.login_status); 
      mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message); 

      findViewById(R.id.sign_in_button).setOnClickListener(
        new View.OnClickListener() { 
         @Override 
         public void onClick(View view) { 
          attemptLogin(); 
         } 
        }); 
     } 

     @Override 
     public boolean onCreateOptionsMenu(Menu menu) { 
      super.onCreateOptionsMenu(menu); 
      getMenuInflater().inflate(R.menu.activity_login_activity_test, menu); 
      return true; 
     } 

     /** 
     * Attempts to sign in or register the account specified by the login form. 
     * If there are form errors (invalid email, missing fields, etc.), the 
     * errors are presented and no actual login attempt is made. 
     */ 
     public void attemptLogin() { 
      if (mAuthTask != null) { 
       return; 
      } 

      // Reset errors. 
      mEmailView.setError(null); 
      mPasswordView.setError(null); 

      // Store values at the time of the login attempt. 
      mEmail = mEmailView.getText().toString(); 
      mPassword = mPasswordView.getText().toString(); 

      boolean cancel = false; 
      View focusView = null; 

      // Check for a valid password. 
      if (TextUtils.isEmpty(mPassword)) { 
       mPasswordView.setError(getString(R.string.error_field_required)); 
       focusView = mPasswordView; 
       cancel = true; 
      } else if (mPassword.length() < 4) { 
       mPasswordView.setError(getString(R.string.error_invalid_password)); 
       focusView = mPasswordView; 
       cancel = true; 
      } 

      // Check for a valid email address. 
      if (TextUtils.isEmpty(mEmail)) { 
       mEmailView.setError(getString(R.string.error_field_required)); 
       focusView = mEmailView; 
       cancel = true; 
      } else if (!mEmail.contains("@")) { 
       mEmailView.setError(getString(R.string.error_invalid_email)); 
       focusView = mEmailView; 
       cancel = true; 
      } 

      if (cancel) { 
       // There was an error; don't attempt login and focus the first 
       // form field with an error. 
       focusView.requestFocus(); 
      } else { 
       // Show a progress spinner, and kick off a background task to 
       // perform the user login attempt. 
       mLoginStatusMessageView.setText(R.string.login_progress_signing_in); 
       showProgress(true); 
       mAuthTask = new UserLoginTask(); 
       mAuthTask.execute((Void) null); 
      } 
     } 

     /** 
     * Shows the progress UI and hides the login form. 
     */ 
     @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) 
     private void showProgress(final boolean show) { 
      // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow 
      // for very easy animations. If available, use these APIs to fade-in 
      // the progress spinner. 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { 
       int shortAnimTime = getResources().getInteger(
         android.R.integer.config_shortAnimTime); 

       mLoginStatusView.setVisibility(View.VISIBLE); 
       mLoginStatusView.animate().setDuration(shortAnimTime) 
         .alpha(show ? 1 : 0) 
         .setListener(new AnimatorListenerAdapter() { 
          @Override 
          public void onAnimationEnd(Animator animation) { 
           mLoginStatusView.setVisibility(show ? View.VISIBLE 
             : View.GONE); 
          } 
         }); 

       mLoginFormView.setVisibility(View.VISIBLE); 
       mLoginFormView.animate().setDuration(shortAnimTime) 
         .alpha(show ? 0 : 1) 
         .setListener(new AnimatorListenerAdapter() { 
          @Override 
          public void onAnimationEnd(Animator animation) { 
           mLoginFormView.setVisibility(show ? View.GONE 
             : View.VISIBLE); 
          } 
         }); 
      } else { 
       // The ViewPropertyAnimator APIs are not available, so simply show 
       // and hide the relevant UI components. 
       mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE); 
       mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); 
      } 
     } 

     /** 
     * Represents an asynchronous login/registration task used to authenticate 
     * the user. 
     */ 
     public class UserLoginTask extends AsyncTask<Void, Void, Boolean> { 
      @Override 
      protected Boolean doInBackground(Void... params) { 
       // TODO: attempt authentication against a network service. 

       try { 
        // Simulate network access. 
        Thread.sleep(2000); 
       } catch (InterruptedException e) { 
        return false; 
       } 

       for (String credential : DUMMY_CREDENTIALS) { 
        String[] pieces = credential.split(":"); 
        if (pieces[0].equals(mEmail)) { 
         // Account exists, return true if the password matches. 
         return pieces[1].equals(mPassword); 
        } 
       } 

       // TODO: register the new account here. 
       return true; 
      } 

      @Override 
      protected void onPostExecute(final Boolean success) { 
       mAuthTask = null; 
       showProgress(false); 

       if (success) { 
        finish(); 
       } else { 
        mPasswordView 
          .setError(getString(R.string.error_incorrect_password)); 
        mPasswordView.requestFocus(); 
       } 
      } 

      @Override 
      protected void onCancelled() { 
       mAuthTask = null; 
       showProgress(false); 
      } 
     } 
    } 

UserLoginTask是你想要做您的身份验证。这将允许您在尝试登录时显示微调。 'onPostExecute'将成为您验证后移至下一个活动的位置,或者返回登录屏幕,并为用户提供一条消息,例如无效密码。

请注意,模板包含dummy_credentials,如果您使用服务器进行身份验证,并且它附带电子邮件和密码textEdits,则不需要该模板,但您可以将其更改为任何所需内容。

+0

如果你看看这段代码,你会发现你可以删除一些东西。例如密码验证/电子邮件正确性等。您将不得不修改代码以适合您希望用户插入的内容。 – Quantico 2013-02-12 20:42:53

+0

是的,这是谷歌的例子。 – Mike 2013-02-12 22:54:23

+0

是的,我说:在ADT下创建新的活动选择:登录活动这将为您生成以下模板代码。 – Quantico 2013-02-13 04:03:38

0

你需要实现扩展AsyncTask一个新的类,做的大量工作的一个名为doInBackground函数内部,并使用其他常见方法(如onProgressUpdate)将结果发布到UI线程。快速的网络搜索“android asynctask tutorial”将会产生一些好的结果供你学习。

+0

我更新了代码,你可以看看吗? – Mike 2013-02-13 14:12:07

0

你的AsyncTask可能是这个样子:

private class DownloadFilesTask extends AsyncTask<Login, Void, Tours> { 
    protected void onPreExecute(){ 
     //show the dialog here 
    } 

    protected Long doInBackground(URL... urls) { 
     Tours response = getInfo.getTours(Login.mUsername, Login.mPassword); 
     return response; 
    } 


    protected void onPostExecute(Long result) { 
     //hide the dialog here 
    } 
} 

我不知道有足够的了解您的项目,使之成为在下降,你必须定制它了一点,但总体“方式“将与此类似。

+0

我更新了代码,你可以看一下吗? – Mike 2013-02-13 14:11:40