AsyncTask 和 SOAP 网络服务
Posted
技术标签:
【中文标题】AsyncTask 和 SOAP 网络服务【英文标题】:AsyncTask and SOAP webservices 【发布时间】: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。 【参考方案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<String, String, String>
更改为 RetrieveFeedTask 类扩展 AsyncTask<String, String, Void>
。第三种是doInBackground()
的返回类型,所以你需要将String doInBackground()
改为Void doInBackground()
并修改方法返回null。
class RetrieveFeedTask 扩展了 AsyncTask你可以使用这个(带有 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 方法中作为参数接收。
【讨论】:
以上是关于AsyncTask 和 SOAP 网络服务的主要内容,如果未能解决你的问题,请参考以下文章
SOAP 和 REST Web 服务有啥区别? SOAP 可以是 RESTful 的吗?
谁能用 service 和 asyncTask 向我解释我的简单应用程序中的服务?
web service011——使用soap1.1和soap1.2发布和调用服务