这两天由于工作需要,学习了下android通过C#的webservice与服务端进行数据通信(sqlserver)。中间遇到几个问题,总结下,以备后期使用时注意。
Android端调用webservice的代码:
/**
* 上传设备状态信息信息
*
* @param data 打包好的数据
* @return 成功与否的相关字符串
*/
publicstatic StringuploadLocation(String data) {
METHOD_NAME = "UploadLocation";
try {
SoapObject soapObject = new SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo propertyInfo = new PropertyInfo();
propertyInfo.setName("LocationInfo");
propertyInfo.setValue(data);
soapObject.addProperty(propertyInfo);
SoapSerializationEnvelopeenvelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(soapObject);
HttpTransportSE httpTranstation =new HttpTransportSE(URL);
httpTranstation.debug = true;
httpTranstation.call(NAMESPACE + METHOD_NAME, envelope);
Object result = (Object)envelope.getResponse().toString();
if (result != null) {
Log.i("WebserviceControlClass", result.toString());
return result.toString();
}
return "返回数据为空";
} catch (Exception e) {
e.printStackTrace();
Log.i("WebserviceControlClass", "设备信息上传出现异常" + e.toString());
return "出现异常";
}
}
需要注意的地方:
1. propertyInfo.setName("LocationInfo");参数要与webservice方法中参数保持一致,否则获取不到数据。
2. envelope.dotNet = true;我用的是dotwebservice 的协议,并且用的rpc方式所以,这里要用true.
3. httpTranstation.debug = true;需要用调试模式,所以为true
因为与服务器之间进行通信,是一个耗时的操作,所最后不要再主线程中直接写访问代码。应该通过异步的方式,请求数据。
importandroid.os.AsyncTask; /** * Created by ZHao on 2016/4/15. */ public class WebServiceTask extends AsyncTask<String, Integer, String> { public WebServiceTask() { } @Override protected void onPreExecute() { } @Override protected String doInBackground(String... params) { return WebserviceControlClass.uploadLocation(params[0]);//这里返回webServices请求的值。 } @Override protected void onProgressUpdate(Integer... progress) { } @Override protected void onPostExecute(String result) { } }
然后配合handler实现数据的收发。
/** * 处理设备状态信息 上传和回掉结果 */ public Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 0) { WebServiceTask task = new WebServiceTask(); String result = ""; try { task.execute((String) msg.obj); //设置请求参数 result = task.get(5000, TimeUnit.MILLISECONDS); //获取返回值,设置超时时间。 } catch (InterruptedException e) { e.printStackTrace(); result = "出现异常InterruptedException"; } catch (ExecutionException e) { e.printStackTrace(); result = "出现异常ExecutionException"; } catch (TimeoutException e) { e.printStackTrace(); result = "出现异常TimeoutException"; } catch (Exception e) { result = "出现异常 Exception"; } LogTools.i(TAG, result); } } };
因为我需要将一个对象传递到服务端,android调用webservice传输复杂对象,该怎么做呢?
具体的实现方式如下。
首先是android具体操作代码,这里通过handler将locationData传递给异步类,进行数据上传。
dbDeviceStateClass = new DbDeviceStateClass(); dbDeviceStateClass.setDevice_id(CommonUtil.getDeviceId(this));//设备id LogTools.i(TAG, CommonUtil.getDeviceId(this)); dbDeviceStateClass.setDevice_state_current_lat(String.valueOf(geoLat));//精度 dbDeviceStateClass.setDevice_state_current_lon(String.valueOf(geoLng));//纬度 dbDeviceStateClass.setDevice_city(location.getCity());//所在城市 dbDeviceStateClass.setDevice_province(location.getProvince());//所在省 locationData = ConvertForJsonModelControl.ConvertToJsonForDeviceState(dbDeviceStateClass); Message msg = handler.obtainMessage(); msg.what = 0; msg.obj = locationData; handler.sendMessageDelayed(msg, 10);
需要注意的是,传递的对象,android和服务端需要保持一致,在android将数据打包成JSONObject,在服务端在解析出来,服务端代码在下面贴出。
** * 将设备状态信息实体类转换为json对象 * @param dbDeviceStateClass * @return */ public static String ConvertToJsonForDeviceState(DbDeviceStateClass dbDeviceStateClass) { String jsonStr = ""; JSONObject modelJsonObject = new JSONObject(); try { modelJsonObject.put("device_state_id", 0); modelJsonObject.put("device_id", dbDeviceStateClass.getDevice_id()); modelJsonObject.put("user_name", dbDeviceStateClass.getUser_name()); modelJsonObject.put("device_city", dbDeviceStateClass.getDevice_city()); modelJsonObject.put("device_province", dbDeviceStateClass.getDevice_province()); modelJsonObject.put("device_location", dbDeviceStateClass.getDevice_location()); modelJsonObject.put("device_state_current_speed", dbDeviceStateClass.getDevice_state_current_speed()); modelJsonObject.put("device_state_update_time", dbDeviceStateClass.getDevice_state_update_time()); modelJsonObject.put("device_state_connect_net", dbDeviceStateClass.getDevice_state_connect_net()); modelJsonObject.put("device_state_current_lat", dbDeviceStateClass.getDevice_state_current_lat()); modelJsonObject.put("device_state_current_lon", dbDeviceStateClass.getDevice_state_current_lon()); jsonStr = modelJsonObject.toString(); } catch (JSONException e) { e.printStackTrace(); } return jsonStr; }
接下来是服务端sebservice的具体方法代码,其中这个db_table_device_state 数据类要和android端的DbDeviceStateClass数据类保持一致,才能通过
device_state=(db_table_device_state)jsonSerializer.Deserialize(newJsonTextReader(strReader),typeof(db_table_device_state));将JSONObject数据解析出来。
/// <summary> /// 保存设备状态到数据库 /// </summary> /// <param name="LocationInfo"></param> /// <returns></returns> [WebMethod] public string UploadLocation(string LocationInfo) { string strJson = ""; db_table_device_state device_state = null; try { using (var db = new hudProjecterDBEntities()) { JsonSerializer jsonSerializer = new JsonSerializer(); StringReader strReader = new StringReader(LocationInfo); device_state = (db_table_device_state)jsonSerializer.Deserialize(new JsonTextReader(strReader), typeof(db_table_device_state)); if (device_state != null) { var mdevice = db.db_table_device.FirstOrDefault(p => p.device_id == device_state.device_id); strJson = "mdevice:" + mdevice; if (mdevice != null) { db_table_device_state mdevicestate = new db_table_device_state(); mdevicestate.device_state_current_lat = device_state.device_state_current_lat; mdevicestate.device_state_current_lon = device_state.device_state_current_lon; mdevicestate.device_state_connect_net = device_state.device_state_connect_net; mdevicestate.device_state_update_time = DateTime.Now; mdevicestate.device_state_current_speed = device_state.device_state_current_speed; db.db_table_device_state.Add(mdevicestate); db.SaveChanges(); strJson = "[{\"Code\":\"200\",\"Message\":\"操作成功!\"}]"; } } } } catch (Exception ex) { strJson = "[{\"Code\":\"500\",\"Message\":\"服务器出错!\"}]"; } return strJson; }
好了,整体流程代码和需要注意的问题都在这里了。吼吼!!