【问题标题】:AsyncTask and SOAP webservicesAsyncTask 和 SOAP 网络服务
【发布时间】:2017-12-11 23:52:37
【问题描述】:

我是 SOAP webservices 和 AsyncTask 的新手,我正在开发一个使用 SOAP webservices 进行登录的应用程序。 我试图在 onCreate 方法中完成所有工作,但我得到了 android.os.NetworkOnMainThreadException。

所以我尝试使用 AsyncTask, 但我无法在 RetrieveFeedTask 类中获得对 emailText 和 passwordText 的引用。

这是我的代码:

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {


    private static String SOAP_ACTION = "intentionally hided";
    private static String NAMESPACE = "intentionally hided";
    private static String METHOD_NAME = "intentionally hided";
    private static String URL = "intentionally hided";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        final EditText emailText = (EditText) findViewById(R.id.emailText);
        final EditText passwordText = (EditText) findViewById(R.id.passwordText);
        Button loginButton = (Button) findViewById(R.id.button_login);

        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                new RetrieveFeedTask().execute();

            }
        });
    }

    class RetrieveFeedTask extends AsyncTask<String, String, String> {



        protected String doInBackground(String... urls) {


            SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

            request.addProperty("userName", emailText.getText().toString());
            request.addProperty("userPassword", passwordText.getText().toString());

            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

            envelope.setOutputSoapObject(request);
            envelope.dotNet = true;

            try {
                HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

                androidHttpTransport.call(SOAP_ACTION, envelope);

                SoapObject result = (SoapObject) envelope.bodyIn;
                if (result != null) {
                    Toast.makeText(getApplicationContext(), "Login Successful!", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(getApplicationContext(), "Login Failed!", Toast.LENGTH_LONG).show();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

【问题讨论】:

  • 这里似乎有一篇文章 -> helloandroid.com/tutorials/… 解释了如何做到这一点。但是,如果可能的话,我会研究 json 和 rest API,而不是 SOAP Webservices。

标签: android web-services soap android-asynctask android-studio-2.3


【解决方案1】:

您可以将视图的文本值传递给异步任务的构造函数,并通过内部引用访问它们。

class RetrieveFeedTask extends AsyncTask<String, String, String> {

    private String emailText, passwordText;

    RetrieveFeedTask(String emailText, String passwordText) {
        this.emailText = emailText;
        this.passwordText = passwordText;
    }

    protected String doInBackground(String... urls) {
        ...
    }
}

然后你可以这样称呼它:

 new RetrieveFeedTask(
        emailText.getText().toString(), 
        passwordText.getText().toString()
 ).execute();

或者,您可以将参数作为数组直接传递给doInBackground()

protected Void doInBackground(String... urls) {
    String email = urls[0];    
    String password = urls[1]; 
    ....  
}

然后这样称呼它:

String[] urls = { 
    emailText.getText().toString(), 
    passwordText.getText().toString() 
};

new RetrieveFeedTask().execute(urls);

【讨论】:

  • 感谢您的回复,我做了同样的事情,但问题仍然存在,说“必须从 UI 线程调用方法 getText”。
  • 对不起,我看错了你的问题。我已经更新了我的答案。您不能从非 UI 线程修改视图的状态。您收到该错误的原因是 doInBackground() 在非 UI 线程上运行。
  • 谢谢,这解决了问题,但现在它说应该从 doInBackground 方法返回一些东西,而我没有什么可返回的,你能在这方面帮忙吗?
  • 没问题。尝试将 RetrieveFeedTask 类扩展 AsyncTask&lt;String, String, String&gt; 更改为 RetrieveFeedTask 类扩展 AsyncTask&lt;String, String, Void&gt;。第三种是doInBackground()的返回类型,所以你需要将String doInBackground()改为Void doInBackground()并修改方法返回null。
  • class RetrieveFeedTask 扩展了 AsyncTask 并且还将返回类型更改为 void 的 doInBackground 但仍然在 void protected void doInBacground 错误处给出错误;尝试使用不完整的返回类型
【解决方案2】:

你可以使用这个(带有 onPreExecute 和 onPostExecute 的 AsyncTask,但没有 NetworkOnMainThreadException):

class RetrieveFeedTask extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... urls) {

        String result = "";

        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

        request.addProperty("userName", emailText.getText().toString());
        request.addProperty("userPassword", passwordText.getText().toString());

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

        envelope.setOutputSoapObject(request);
        envelope.dotNet = true;

        try {
            HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

            androidHttpTransport.call(SOAP_ACTION, envelope);

            SoapObject result = (SoapObject) envelope.bodyIn;
            if (result != null) {
                result = "Login Successful!";
            } else {
                result = "Login Failed!";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    protected String onPostExecute(String result) {
        super.onPostExecute(result);

        if (result.equals("Login Successful!")) {
            Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(getApplicationContext(), "Login Failed!", Toast.LENGTH_LONG).show();
        }
    }
}

【讨论】:

  • 谢谢,在我尝试过你的解决方案之前我得到了一个解决方案,它就像魅力一样。
【解决方案3】:

您将 emailText 和 passwordText 直接传递到 AsyncTask 中,您只需要进行一些小改动:

首先在您的 onClick 侦听器中:

字符串电子邮件 = emailText.getText().toString();

字符串密码 = passwordText.getText().toString();

new RetrieveFeedTask().execute(email, password);

第二个在你的 AsyncTask doInBackground 方法中:

字符串电子邮件 = urls[0];

字符串密码 = urls[1];

您几乎可以将任意值传递给 AsyncTask 的执行方法,这些值在其 doInBackground 方法中作为参数接收。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多