如何使用kso​​ap2和axis2 Web服务正确使用asynctask

时间:2013-06-06 19:08:43

标签: java android web-services android-asynctask android-ksoap2

我使用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?如果有人可以指导我阅读涵盖这些问题的教程,那就太棒了。我也很感激你对这些问题的任何回答。提前谢谢。

3 个答案:

答案 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()。