注意:
本文主要介绍安卓如何调用webservice进行开发,以及我的需求中的UI组件使用;写的不尽如人意的地方,请见谅~
概述如下:
- 环境 :Android Studio 1.4 for Mac
- 语言 :如果我没猜错的话,应该是Java
- 特点 :简单、直接、暴力,绝对让你有快感!!!
我准备后期再调整页面的排版,大家随意~
下面正式开始
1.Webservice接口 -- querydetail方法
querydetail
测试测试窗体只能用于来自本地计算机的请求。
SOAP 1.1以下是 SOAP 1.2 请求和响应示例。所显示的占位符需替换为实际值。
POST /testsdk/SDKService.asmx
HTTP/1.1Host: ***.***.***.*** <!-- 主机地址 -->
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://microsoft.com/webservices/querydetail"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<querydetail xmlns="http://microsoft.com/webservices/">
<user>string</user> <!-- 参数 -->
</querydetail>
</soap:Body>
</soap:Envelope>
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<querydetailResponse xmlns="http://microsoft.com/webservices/">
<querydetailResult>string</querydetailResult>
</querydetailResponse>
</soap:Body>
</soap:Envelope>
SOAP 1.2
以下是 SOAP 1.2 请求和响应示例。所显示的占位符需替换为实际值。
POST /testsdk/SDKService.asmx HTTP/1.1
Host: ***.***.***.*** <!-- 主机地址 -->
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<querydetail xmlns="http://microsoft.com/webservices/">
<user>string</user> <!-- 参数 -->
</querydetail>
</soap12:Body>
</soap12:Envelope>
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<querydetailResponse xmlns="http://microsoft.com/webservices/">
<querydetailResult>string</querydetailResult>
</querydetailResponse>
</soap12:Body>
</soap12:Envelope>
简要说明
我们在Android中调用webservice接口所需要如下:
Service URL | Name Space | Method Name | SoapAction |
---|---|---|---|
服务器地址 | http://microsoft.com/webservices/ | querydetail | NameSpace+MethodName |
ServiceURL:服务器地址,打开你自己的webservice就看见了,这个地址下有很多方法名;
NameSpace:命名空间,这个很好找,请看上面代码块中
<querydetail xmlns="http://microsoft.com/webservices/">
<user>string</user> <!-- 参数 -->
</querydetail>
MethodName:方法名"querydetail",这个不需要多说
SoapAction:命名空间+方法名;有两个地方可以找到它;
1.看本接口里面有没有写,如果有,肯定是下面这样
SOAPAction: "http://microsoft.com/webservices/querydetail"
2.查看你的WDSL文档,找到下面这种样式的
<wsdl:operation name="querydetail">
<soap12:operation soapAction="http://microsoft.com/webservices/querydetail" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
2.开始写布局
2.1 -- 主页面
activity_main.xml
这个布局大家就凑合看吧,别较真~
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<EditText android:id="@+id/inputTextField"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:inputType="textPhonetic"
android:hint="搜索框"/>
<Button android:id="@+id/queryButton"
android:layout_below="@id/inputTextField"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:text="查询" />
<TextView android:id="@+id/no_lb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="数量"
android:textSize="20dp"
android:layout_below="@id/queryButton"
android:layout_marginTop="20dp"
android:layout_centerHorizontal="true"/>
<TextView android:id="@+id/name_lb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="名称"
android:textSize="20dp"
android:layout_below="@+id/queryButton"
android:layout_marginTop="20dp"/>
<TextView android:id="@+id/gender_lb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="性别"
android:textSize="20dp"
android:layout_below="@id/queryButton"
android:layout_marginTop="20dp"
android:layout_alignParentRight="true"/>
<ListView android:id="@+id/resultLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/no_lb"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="20dp">
</ListView>
</RelativeLayout>
2.2 -- listView内部布局
item_ activity_main_list_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<View android:layout_width="1px"
android:layout_height="fill_parent"
android:background="#B8B8B8"
android:visibility="visible"/>
<TextView android:id="@+id/no_lb"
android:layout_width="200dip"
android:layout_height="30dp"
android:textColor="#CD3700"
android:textSize="15sp"/>
<View android:layout_width="1px"
android:layout_height="fill_parent"
android:background="#B8B8B8"
android:visibility="visible"/>
<TextView android:id="@+id/name_lb"
android:layout_width="100dip"
android:layout_height="30dp"
android:textColor="#000000"
android:textSize="15sp"/>
<View android:layout_width="1px"
android:layout_height="fill_parent"
android:background="#B8B8B8"
android:visibility="visible"/>
<TextView android:id="@+id/gender_lb"
android:layout_width="85dip"
android:layout_height="30dp"
android:textColor="#000000"
android:textSize="15sp"/>
<View android:layout_width="1px"
android:layout_height="fill_parent"
android:background="#B8B8B8"
android:visibility="visible"/>
</LinearLayout>
简要说明
这个xml文件其实是activity_main.xml中listView的自定义布局;
下面这个view布局其实是分割线
<View android:layout_width="1px"
android:layout_height="fill_parent"
android:background="#B8B8B8"
android:visibility="visible"/>
3.开始写代码
MainActivity.java
public class MainActivity extends AppCompatActivity
{
private EditText inputTextField; // 搜索框
private Button queryButton; // 查询按钮
private ListView resultLabel; // 结果展示的listView
private List<QueryDetailModel> queryDetailModels = new ArrayList<>(); // 数据数组
private ResulListViewAdapter resultListViewAdapter; // 适配器
final String serviceUrl = "http://***.***.***/testsdk/SDKService.asmx"; // 服务器地址
final String nameSpace = "http://microsoft.com/webservices/"; // 命名空间
final String methodName = "querydetail"; // 方法名
final String soapAction = nameSpace + methodName; // SOAPACTION
/***
* 优化线程 -- 网上摘的。。
*/
private Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message msg) {
resultListViewAdapter.notifyDataSetChanged();
}
};
/***
* 入口方法 - viewDidLoad
*/
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // 绑定页面
setTitle("查询页面");
initView(); // 初始化控件
selectorMethod(); // 点击事件
}
/***
* 初始化控件
*/
private void initView()
{
inputTextField = (EditText) findViewById(R.id.inputTextField);
queryButton = (Button) findViewById(R.id.queryButton);
resultLabel = (ListView) findViewById(R.id.resultLabel);
// 设置适配器中的数据显示到listView上去
resultListViewAdapter = new ResulListViewAdapter(MainActivity.this, queryDetailModels);
resultLabel.setAdapter(resultListViewAdapter);
}
/***
* 点击事件
*/
private void selectorMethod()
{
queryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String inputText = inputTextField.getText().toString().trim();
System.out.println("输入的内容:" + inputText);
// 开始查询
getDataSource(inputText);
}
});
}
/***
* 开始查询
*/
private void getDataSource(String inputText)
{
SoapObject soapObject = new SoapObject(nameSpace, methodName);
soapObject.addProperty("user", inputText); // "user"是接口中的参数
// new调用webservice方法的SOAP请求信息,并指定版本,也可是VER11
final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
envelope.bodyOut = soapObject;
envelope.dotNet = true;
envelope.setOutputSoapObject(soapObject);
final HttpTransportSE httpTransportSE = new HttpTransportSE(serviceUrl);
new Thread(new Runnable() {
@Override
public void run() {
try {
httpTransportSE.call(soapAction, envelope);
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
// 获取返回的数据
SoapObject object = (SoapObject) envelope.bodyIn;
System.out.println("object是返回的JSON串" + object);
String jsonData = object.getProperty(0).toString();
System.out.println("JSON的数据是:" + jsonData);
Log.d("xxxxxx",jsonData);
if (jsonData == null || jsonData.equals("anyType{}")) {
Log.d("success","12345678");
} else {
Type listType = new TypeToken<LinkedList<QueryDetailModel>>() {}.getType();
Gson gson = new Gson();
queryDetailModels.clear();
final LinkedList<QueryDetailModel> queryDetailModels = gson.fromJson(jsonData, listType);
for (QueryDetailModel queryDetailModel : queryDetailModels)
{
queryDetailModels.add(queryDetailModel);
}
// 通知主线程更新 listview
mHandler.sendEmptyMessage(0);
}
}
}).start();
}
}
简要说明
这样一个简单的访问webservice接口的主要方法已经实现了,关于崩溃来讲,应该没有是的事,如果有,请留言;
4.适配器
ResulListViewAdapter.java
public class ResulListViewAdapter extends BaseAdapter
{
// 1.创建一个上下文对象
private Context context;
private List<QueryDetailModel> queryDetailModels;
// 2.带参类方法
public ListViewAdapter(Context context, List<QueryDetailModel> queryDetailModels)
{
this.context = context;
this.queryDetailModels = queryDetailModels;
}
// 展示多少数据
@Override
public int getCount()
{
return queryDetailModels.size();
}
// 获取当前数据,从0开始
@Override
public QueryDetailModel getItem(int position)
{
return queryDetailModels.get(position);
}
// 获取当前是第几个
@Override
public long getItemId(int position)
{
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
// 调试语句
System.out.println("getView ----" + position + " " + convertView);
// 注意,这个是一个自定义类,类中有要的控件
Holder holder;
if (convertView == null) {
// 上下文关联自定义的view
convertView = LayoutInflater.from(context).inflate(R.layout.item_ activity_main_list_view, null);
holder = new Holder();
holder.no_lb = (TextView)convertView.findViewById(R.id.no_lb);
holder.name_lb = (TextView) convertView.findViewById(R.id.name_lb);
holder.gender_lb = (TextView) convertView.findViewById(R.id.gender_lb);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
QueryDetailModel item = getItem(position);
holder.no_lb.setText(item.getNo());
holder.name_lb.setText(item.getName());
holder.gender_lb.setText(item.getGender());
return convertView;
}
// 内部类,主要是布局文件中要展示的数据控件
static class Holder
{
TextView no_lb;
TextView name_lb;
TextView gender_lb;
}
}
简要说明
适配器的在我这Demo中的主要作用就是给自定义listView的item传数据用的,具体和高深的请去网上查阅;我这里写的很Low。
5.实体类
QueryDetailModel.java
public class QueryDetailModel
{
private String no; // 编号
private String name; // 姓名
private String gender; // 性别
public String getNo()
{
return no;
}
public void setNo(String no)
{
this.no = no;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getGender()
{
return gender;
}
public void setGender(String gender)
{
this.gender = gender;
}
简要说明
根据获取到的JSON,把相关参数写上去,直接Setter&Getter就可以了,随你自己的习惯。
总结
希望大家喜欢我写的东西,转发收藏什么的,多多益善~
上面的所有代码都是复制粘贴我自己的,有些类名、变量名、参数名都是我后改的,有可能改错了,但是我相信,细心的你一定会发现。
最后,如果你有更好的,请回复我,并粘贴你的资料地址。
有事私信
WangJun 20161217