注意:
本文主要介紹安卓如何調用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