【问题标题】:Android Async Task Error with ClientServiceClientService 的 Android 异步任务错误
【发布时间】:2013-03-13 19:27:24
【问题描述】:

我正在创建一个运行 Windows 服务的简单系统,其中包含一个用户表,并且我想通过向该服务发送一些内容来验证某人的登录凭据。我正在尝试发送他们的用户名和密码,但我的异步任务一直出错。我知道你不应该在里面乱用 UI 的东西,而我不是。最初我打电话给那里的另一个活动,但我评论了它。现在 doInBackground 中唯一的事情是如果验证良好,则将布尔值设置为 true。在异步执行后,我从那里读取值,然后将一个包放在一起移动到下一个地方。我只是不知道这里出了什么问题。自从我在 Android 中编程以来已经有一段时间了,所以也许我错过了一些愚蠢的东西。如果有人可以帮助我,我将不胜感激!谢谢你。这也可能是向服务发送信息的问题?

更新:在清单中添加互联网使用情况后,如果我的 doInBackground 中的程序中有 log.d,它会打印出来。如果我没有它,结果值将保持为假。我的服务和 android 应用程序之间的连接似乎有问题...

import java.util.ArrayList;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class LoginActivity extends Activity {
    private static final int DATA_FROM_MAIN_ACTIVITY = 1;
    private static final String SERVICEURL = "http://localhost:56638/ClientService.svc";
    private EditText userTextBox, passTextBox;
    private Button loginButton;
    private String uName, pass;
    private Boolean result = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        userTextBox = (EditText) findViewById(R.id.userTextBox);
        passTextBox = (EditText) findViewById(R.id.passTextBox);
        loginButton = (Button) findViewById(R.id.loginButton);

        loginButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                uName = userTextBox.getText().toString();
                pass = passTextBox.getText().toString();

                SendLoginMessage task = new SendLoginMessage();
                task.execute(uName, pass);

                if (result.equals(true)) {
                    Intent goToMainScreen = new Intent(getApplicationContext(),
                            MainActivity.class);
                    goToMainScreen.putExtra("username", uName);
                    goToMainScreen.putExtra("password", pass);

                    startActivityForResult(goToMainScreen,
                            DATA_FROM_MAIN_ACTIVITY);
                } else {
                    Toast.makeText(
                            getApplicationContext(),
                            "There was an issue with your username or password.",
                            Toast.LENGTH_LONG).show();
                }

            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    private class SendLoginMessage extends AsyncTask<String, String, Void> {
        @Override
        protected void onPreExecute() {
            // Log.d("message almost at server, " + textFromArea, selected,
            // null);
        }

        @Override
        protected Void doInBackground(String... names) {
            ArrayList<NameValuePair> postParams = new ArrayList<NameValuePair>();
            postParams.add(new BasicNameValuePair("username", names[0]));
            postParams.add(new BasicNameValuePair("password", names[1]));

            String response = null;

            try {
                response = HttpClient.executeHttpPost(SERVICEURL, postParams);

                String newResponse = response.toString();
                newResponse = newResponse.replaceAll("\\s+", "");

                // if user was authenticated...
                if (newResponse.equals(true)) {
                    result = true;
                    // creating an intent to take user to next page.
                    // load their DB objects on the
                    // on create in other activity
                    // pass the username/password to next activity
                    // then make a request to the server for their database
                    // objects.
                    // Intent goToMainScreen = new
                    // Intent(getApplicationContext(), MainActivity.class);
                    // goToMainScreen.putExtra("username", names[0]);
                    // goToMainScreen.putExtra("password", names[1]);

                    // startActivityForResult(goToMainScreen,
                    // DATA_FROM_MAIN_ACTIVITY);
                }

            } catch (Exception e) {
                Log.d("ERROR", "exception in background");
            }

            return null;

        }

        @Override
        protected void onPostExecute(Void result) {

            // Toast.makeText(getApplicationContext(),
            // .show();

        }

    }

}

【问题讨论】:

  • 您一直遇到的错误是什么?
  • 这可能是一个问题if (newResponse.equals(true)) 它应该是 if (newResponse.equals("true")) 因为你现在正在比较 Strings
  • 我还在清单中添加了互联网使用,但这并没有解决问题。我还将 .equals 更改为字符串检查,但这也没有什么区别。
  • 我可能必须修改我的 Web 服务,以便它知道客户端打算使用哪种方法吧?
  • 可能,但我会先解决其他问题。比如我命名的第一个,而你在execute()中没有正确传递参数

标签: android web-services android-asynctask


【解决方案1】:

这样做:

 private class SendLoginMessage extends AsyncTask<String, String, Boolean> {
    @Override
    protected Boolean doInBackground(String... names) {
        ArrayList<NameValuePair> postParams = new ArrayList<NameValuePair>();
        postParams.add(new BasicNameValuePair("username", names[0]));
        postParams.add(new BasicNameValuePair("password", names[1]));

        String response = null;

        try {
            response = HttpClient.executeHttpPost(SERVICEURL, postParams);

            String newResponse = response.toString();
            newResponse = newResponse.replaceAll("\\s+", "");

            // if user was authenticated...
            if (newResponse.equals("true")) {
                return true;
            }

        } catch (Exception e) {
            Log.d("ERROR", "exception in background");
        }

        return false;

    }

    @Override
    protected void onPostExecute(Boolean result) {
            if (result) {
                Intent goToMainScreen = new Intent(getApplicationContext(),
                        MainActivity.class);
                goToMainScreen.putExtra("username", uName);
                goToMainScreen.putExtra("password", pass);

                startActivityForResult(goToMainScreen,
                        DATA_FROM_MAIN_ACTIVITY);
            } else {
                Toast.makeText(
                        getApplicationContext(),
                        "There was an issue with your username or password.",
                        Toast.LENGTH_LONG).show();
            }
    }

}

在您的onClick() 中只需致电execute()

 uName = userTextBox.getText().toString();
 pass = passTextBox.getText().toString();

 SendLoginMessage task = new SendLoginMessage();
 task.execute(uName, pass);

执行完成后,onPostExecute() 将被调用,您的Activity 将根据结果变量启动。

调用execute() 后不要检查结果变量,因为execute() 是异步调用的。当您检查全局结果变量时,您的 doInBackground() 可能还没有完成。使用我的方法,您不需要全局变量。请在使用任何组件之前仔细阅读文档。

【讨论】:

  • 嘿,非常感谢您对此发表评论。通过你的做事方式,我学到了很多东西。流程更顺畅,更有意义。感谢您报道如此精彩和丰富的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多