我想将一个字符串数组返回给我的Android客户端并填充ListView。 我正在使用SOAP库(org.ksoap2。*)来调用ASP.NET Web服务。
以下是网络服务的代码:
1。 ASP Web服务
Imports ...
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports ...
<WebService(Namespace:="...")>_
<WebService(ConformsTo:=...)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class EnquiryWS
Inherits System.Web.Services.WebService
' Web method
<WebMethod()> _
Public Function GetList() As String()
'Hardcoded list
Return New String() { "item1", "item2", "item3" }
End Function
我通过访问asmx测试了Web服务,没有运行时错误。 我还用一个简单的字符串测试了它,Web服务将字符串返回给Android。像这样:
' Web method
<WebMethod()> _
Public Function GetString() As String
Return "My string."
End Function
2。 Android活动
其次,这是我的Android代码,它调用ASP.NET Web服务。
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
public class MainActivity extends AppCompatActivity {
private ArrayList<String> list;
private ListView listview;
private ArrayAdapter<String> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
new GetPersonList().execute("AsyncTask String");
//...
}
// Inner AsyncTask class
private class GetPersonList extends AsyncTask<String, Integer,String> {
private static final String SOAP_ACTION = "https://myNamespace/GetList";
private static final String METHOD_NAME = "GetList";
private static final String NAMESPACE = "https://myNamespace/";
private static final String URL =
"https://myIISsite/myASMXfile.asmx";
@Override
protected void onPreExecute() {
super.onPreExecute();
// onPreExecute stuff
}
@Override
protected String doInBackground(String... arg) {
String result = null;
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//Create envelope
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
//Required for .net
envelope.dotNet = true;
//Set output SOAP object
envelope.setOutputSoapObject(request);
//Create HTTP call object
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
//Invoke web service
androidHttpTransport.call(SOAP_ACTION, envelope);
//Get the response
SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
//Assign it to response to a static variable
result = response.toString();
} catch (Exception e) {
result = "error " + e.getMessage();
}
return result;
}
@Override
protected void onPostExecute(String result) {
System.out.println("Returned SOAP XML: " + result);
MyFunction(result);
}
}
}
MyFunction是我创建的一种方法,可以做一些额外的工作。
第3。 MyFunction的
这是MyFunction方法代码:
public void MyFunction(String s) {
// Add Webservice response to list
list.add(s);
// Set adapter
adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item1, list);
listview.setAdapter(adapter);
}
我传递给MyFunction的参数是SOAP响应,然后我将它添加到列表并设置适配器。
好的,所以web服务返回一个字符串数组,但 overriden onPostExecute方法正在使用一个字符串,如果我将onPostExecute参数声明为Collection,它显然不会覆盖
这是我在logcat中遇到的错误:
Return SOAP XML: error expected: START_TAG {http://schemas.xmlsoap.org/soap/envelope/}Envelope (position:START_TAG <html>@1:7 in java.io.InputStreamReader@4182d238)
有人可以建议吗?
答案 0 :(得分:0)
我找到了解决方案。我将响应转换为SoapObject而不是SoapPrimitive,原因是因为SoapPrimitive用于原始数据类型,SoapObject支持复合数据类型。因此,我将我的数组转换为SoapObject而不再是SoapPrimitive。
我已经删除了MyFunction()方法,因为我通过覆盖run()在onPostExecute()方法中设置适配器。最后,我添加了一个ProgressDialog,我正在处理onPreExecute()方法中显示ProgressDialog,然后我在onPostExecute()方法中调用dismiss()。
private class GetPersonList extends AsyncTask<Void, Void, String> {
private static final String SOAP_ACTION = "http://myNamespace/myMethod";
private static final String METHOD_NAME = "myMethod";
private static final String NAMESPACE = "http://myNamespace/";
private static final String URL =
"http://myURL/myAsmxFile.asmx";
ProgressDialog progressDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog= ProgressDialog.show(MainActivity.this,
"Wait",
"Retrieving data",
true
);
}
@Override
protected String doInBackground(Void... params) {
String finalResult = null;
//Create request object
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//Create envelope to which we add our request object
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
//Required for .net
envelope.dotNet = true;
//Add the request object to the envelope
envelope.setOutputSoapObject(request);
//Create HTTP call object
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
//Invoke web service
androidHttpTransport.call(SOAP_ACTION, envelope);
// Get the response
// Cast as SoapObject and not SoapPrimitive
SoapObject response = (SoapObject) envelope.getResponse();
//Assign it to response to a static variable
finalResult = response.toString();
// Now loop through the response (loop through the properties)
// and add them to the list
for(int i = 0; i < response.getPropertyCount(); i++) {
list.add(response.getProperty(i).toString());
}
} catch (Exception e) {
System.out.println("######## ERROR " + e.getMessage());
}
return finalResult;
}
@Override
protected void onPostExecute(String str) {
progressDialog.dismiss();
System.out.println("Returned SOAP XML: " + str);
runOnUiThread(new Runnable() {
@Override
public void run() {
// Set adapter
adapter = new ArrayAdapter<String>(MainActivity.this, R.layout.list_item, R.id.product_name, list);
listview.setAdapter(adapter);
}
});
}
}
我听说有另外一种方法可以使用Gson / Json这样做,我会在发现之后发布。
Cheerz