我使用Web服务向导从动态Web项目开发了一个Web服务(遵循教程,所以我不确定我在做什么)。该教程让我安装了axis2插件,所以我假设这是用于生成Web服务的插件。无论如何,当我从浏览器中尝试它时,该服务正在运行,因此该部分没有任何问题。
我的问题是,我想从Android应用程序访问此Web服务。我在过去两天阅读了很多教程,并尝试实现一个,但后来意识到它已经过时了,它试图在主线程中连接到网络,这在android 3.0之后是不允许的。然后我发现了asynctask并尝试了我的手,但有很多我不明白。我找到的教程没有解释任何这些,所以我在这里问。
我在听到关于asynctask之前写的代码在这里:
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
private final String NAMESPACE = "http://eko.erdem.com";
private final String URL = "http://159.20.89.38:9398/EkoBiletTest/services/EkoClass?wsdl";
private final String SOAP_ACTION = "http://eko.erdem.com/homePage";
private final String METHOD_NAME = "homePage";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
String place = "Paris";
String checkinDate = "2013-06-10";
String checkoutDate = "2013-06-12";
//Pass value for place variable of the web service
PropertyInfo placeProp =new PropertyInfo();
placeProp.setName("place");//Define the variable name in the web service method
placeProp.setValue(place);//Define value for place variable
placeProp.setType(String.class);//Define the type of the variable
request.addProperty(placeProp);//Pass properties to the variable
//Pass value for checkinDate variable of the web service
PropertyInfo checkinDateProp =new PropertyInfo();
checkinDateProp.setName("checkinDate");
checkinDateProp.setValue(checkinDate);
checkinDateProp.setType(String.class);
request.addProperty(checkinDateProp);
//Pass value for checkinDate variable of the web service
PropertyInfo checkoutDateProp =new PropertyInfo();
checkoutDateProp.setName("checkoutDate");
checkoutDateProp.setValue(checkoutDate);
checkoutDateProp.setType(String.class);
request.addProperty(checkoutDateProp);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
TextView tv = (TextView) findViewById(R.id.textView);
tv.setText(response.toString());
setContentView(tv);
} catch (Exception e) {
e.printStackTrace();
}
}
@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;
}
}
现在我不知道代码的哪些部分应该在asynctask的哪个函数(doinBackground()等)中。我也不了解asynctask的参数发送系统。例如,如果我想将NAMESPACE,URL,METHOD_NAME等传递给asynctask我该怎么做?我还应该在哪里更新主要活动的textView?如果有人可以指导我阅读涵盖这些问题的教程,那就太棒了。我也很感激你对这些问题的任何回答。提前谢谢。
答案 0 :(得分:3)
任何与网络相关的工作都需要在doInBackground
AsyncTask
方法中完成
将数据发送到asynctask,您需要声明类的传入数据
puclic class MyNetowrkTask extends AsyncTask<String[],Void,Void>
<>
中的第一个参数是即将到来的数据,第二个参数是进度,而thirs是您在完成任务时返回onPostExecute
的结果。
所以传递字符串会做类似的事情
new MyNetworkTask().execute(new String[] {"namespace","url","method"});
在doInBackground
中你得到的数据就像这样
protected Void doInBackground(String... params) {
String[] data = params[0];
String namespace = data[0];
String url = data[1];
String method = data[2];
....
}
UI元素的任何更新都需要在onPostExecute中完成,因此如果你想更新文本视图,则需要在那里完成。
代码不完全正确,但这会让你开始理解
答案 1 :(得分:1)
现在我不知道代码的哪些部分应该在asynctask的哪个函数中(doinBackground()等)
基本上,将大部分工作放在doInBackground()
中,并确保不要尝试从那里更新UI
。任何其他方法都可以更新UI
。显示基本结构的Here is an answer。
另外我不了解asynctask的参数发送系统。例如,如果我想将NAMESPACE,URL,METHOD_NAME等传递给asynctask我应该怎么做?
您可以将execute()
函数中的doInBackground()
函数传递给MyTask task = new MyTask(); // pass variables here to go to the constructor`
task.execute() // anything passed here will be received by doInBackground()`
,如果您希望在doInBackground()
中使用它们,则可以在构造函数中传递它们
Activity
我应该在哪里更新主要活动的textView?
这可以在除Activity
之外的任何方法中完成,具体取决于您何时需要更新它(在任务完成之前,期间或之后)
如果这是Context
的内部类,那么您可以将Context
的成员变量与constructor
一起使用。如果它是一个单独的文件,那么您可能需要将{{1}}传递给任务的{{1}}。
答案 2 :(得分:0)
您应该将执行HTTP请求的代码(可能是try-catch块中的任何内容)放入异步任务的doInBackground()方法中。如果要将各种参数传递给它,可以将它们封装到对象中并传递对象。或者,您可以将它们通过构造函数传递给异步任务,并将它们用于doInBackground()。