android 调用 soap webservice 关键点:
1.引入第三方soap支持包ksoap2: ksoap2-android-assembly-3.3.0-jar-with-dependencies.jar
2.添加网络访问权限: 在 AndroidManifest.xml 文件中添加<uses-permission android:name="android.permission.INTERNET"/>
3.创建 webserviceClient 调用方法:
请读者根据自己的实际情况设置: 网络参数-->这个和你具体调用的webservice 地址方法有关。
以下只是事例:
package com.yueking.web.service;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
/**
* Created by yueking on 14-12-12.
*/
public class PersonService {
public static String getPersonInfo(String id) {
//1.设置网络参数
String url = "http://192.168.1.200:8088/ifaceservice/services/FaceService";
String namespace = "http://service.yueking.com";
String method = "getPersonInfo";
String action = namespace + method;
//2.设置SoapObject 对象
SoapObject soapObject = new SoapObject(namespace, method);
soapObject.addProperty("id", id);
//3.设置SoapSerializationEnvelope 对象
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(soapObject);
//4.设置HttpTransportSE 进行访问
HttpTransportSE se = new HttpTransportSE(url);
String result = null;
try {
//5.调用远程方法 并获取结果
se.call(action, envelope);
Object rcv = envelope.getResponse();
if (rcv != null) {
result = rcv.toString();
}
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
return result;
}
}
=====================================================================
有了上面的webservice Client调用方法后 我们就可以在程序中使用了。
===================Android 2.3 以后 请注意 webservice调用 重点来了===================
由于 Android 2.3 版本以后 系统禁止主UI线程 访问网络 等占用时间的操作;
因此在 2.3 以上系统你可能会遇到 实体机器访问网络出现问题的情况;
一下介绍两种方案使得 2.3以后的程序实体正常调用webservcie的方案:
【方案1】--不推荐 这种方案只适合程序测试时使用
请在主Activity 类上的 onCreate 方法开始部分添加以下代码:
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork() // or .detectAll() for all detectable problems
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build());
这样程序就能像Android 2.2 一样的方式使用webservice了
但是这种方式是不推荐的或者是不好的方案
由于把UI主线程中添加 耗时 甚至稳定的网络访问和UI捆绑在一起 网络的意外状况会影响UI界面 这是2.3以后不允许的。
【方案2】:推荐方法
方案思路:
1.开辟子线程 进行网络操作
2.使用Handler 类进行 UI 界面更新 :
?为什么不直接在子线程中更新UI呢
A: android 并不支持才子线程中访问修改UI
所以需要使用Handler 收到子线程结束的信号后,有handler 进行UI的更新
代码如下:
package com.yueking.web;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
import com.yueking.web.service.PersonService;
public class MainActivity extends Activity {
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 方案一
// StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
// .detectDiskReads()
// .detectDiskWrites()
// .detectNetwork() // or .detectAll() for all detectable problems
// .penaltyLog()
// .build());
// StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
// .detectLeakedSqlLiteObjects()
// .detectLeakedClosableObjects()
// .penaltyLog()
// .penaltyDeath()
// .build());
}
/**
* 方案二 主UI线程调用 远程webservice 通过开辟子线程
* @param view
*/
public void rcpServiceOpen(View view) {
final TextView msg = (TextView) findViewById(R.id.textView_msg);
//1.创建一个Handler 进行UI的更新和子线程数据的获取
final Handler handler = new Handler(){
@Override
public void handleMessage(Message m) {
super.handleMessage(m);
Bundle data = m.getData();//获取子线程传来的数据
String personID = data.getString("personID");
msg.setText("yahoo..."+personID);
//todo 这个地方是你进行UI操作的....
}
};
//2.创建并运行子线程 程序实际是 执行到run方法结尾处的 handler.sendMessage 方法后 handler 类的 handleMessage 方法得到消息进行执行
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
String personInfo = PersonService.getPersonInfo("yuekingID41280119820302");
Message m = new Message();
Bundle data = new Bundle();
data.putString("personID",personInfo);
m.setData(data);//设置 子线程数据结果传入到 handler 类以便 更新UI时使用
handler.sendMessage(m);//todo 这个是子线程结束时调用的方法 通知 handler 执行 handleMessage(Message msg) 方法进行UI操作
}
});
thread.start();
}
}
如果你不需要子线程 传输数据时直接 在程序末尾调用 handler 的
handler.sendEmptyMessage(0) 方法发送空消息 就好。
以上就是这些。
注:以上两个方案均思路整理至互联网,因为便于以后管理本人凌乱的blog
有本人整理的文章便无耻的贴上原创的标(不要脸啦!)。