android webService 异步访问

来源:互联网 发布:c语言小写变大写 编辑:程序博客网 时间:2021/04/12 14:13
 android 使用webservices 需要注意几个问题,这也是我在项目中遇到的,总结一下,和大家分享

1.在AndoirdManifest.xml添加网络访问权限。

2.android访问webServices的代码编写。

3.android使用webService的代码不能放在主线程(uI)线程。如果必须要放在主线程可以使用StrictMode。下面具体说明。

4.android使用webService放在后台现场执行的方法。

5.需要线程返回值的方法。

下面对上面的问题加以说明

1.在AndroidManifest.xml添加

 <uses-permission android:name="android.permission.INTERNET" />

 

2.android使用webServices需要使用第三方jar。我在项目中使用的是通用的ksoap2 (具体文件名为:ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar)

 请求服务的时候,在ksoap2中最低需要三个参数。

  1) 请求服务的Url

  2) 服务的命名空间

  3) 服务的方法名称

 一般来说知道Url之后,通过分析wsdl可以知道2,3 两个参数。

  构造请求服务的代码块如下:

 

public String requestServer(String uId) {
 try { SoapObject rpc = new SoapObject(http://tempuri.org/, getDeviceId());//getDeviceId是调用服务的方法名称rpc.addProperty("deviceid", uId);//设置请求参数SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);envelope.bodyOut = rpc;envelope.dotNet = true;envelope.setOutputSoapObject(rpc);HttpTransportSE ht = new HttpTransportSE(WEBSERVICE_URL,5000); //WEBSERVICE_URL是请求webServices的urlht.debug = true;ht.call(SOAP_ACTION, envelope);Object obj = (Object)envelope.getResponse();if(obj !=null){return obj.toString();}return "" ; }catch (IOException e) {e.printStackTrace(); } return ""; }}

上面的这段代码就是请求webservices 的代码。在我本机中是可以用的代码。

3 如果把这个段代码放在onCreate方法内部执行,初始化请求数据的时候,系统肯定报错。打印异常。这是因为,像请求网络这种费时操作不能放在主线程执行。但是如果必须放在主线程执行可以使用StrictMode

具体方法如下:

在onCreate方法开始处添加如下代码: 

 

try{        int applicationFlags = this.getApplicationInfo().flags;        if ((applicationFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                .detectDiskReads()                .detectDiskWrites()                .detectNetwork()                .penaltyLog()                .build());            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                .detectLeakedSqlLiteObjects()                .penaltyLog()                .penaltyDeath()                .build());        }}catch (Throwable throwable) {    Log.v("StrictMode", "... is not available. Punting...");   }//添加异常捕获是因为在android低版本是不支持StricMode的。


添加完这段代码之后,在主线程内部运行请求webservices代码,就不会出错了。但是在具体的项目,比较好的做法,还是使用多线程。就是将费时的操作,单独放在一个线程内部执行。

我的实现思路是:

1.发个消息。

2.handler接受消息后,启动线程,执行请求webServices操作

具体实现的代码如下:

 

  Message msg = handler.obtainMessage();  msg.what = 111; //具体数值可以自己任意设置。我再次随便设置111  handler.sendMessageDelayed(msg,500)

 

处理消息的handler代码:

public Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {if(msg.what==111)WebServicesTask task =  new WebServicesTask();         String result = ""; try {task.execute("idxxx"); //设置请求参数 result = task.get(5000, TimeUnit.MILLISECONDS); //获取返回值,设置超时时间。     }catch (InterruptedException e) {         e.printStackTrace();      result= "";        } catch (ExecutionException e) {           e.printStackTrace();        result= "";       } catch (TimeoutException e) {       e.printStackTrace();    result= "";      }}}




 WebServicesTask类是一个AsyncTask ,之所以用Task有两个原因

1.异步操作(后台)。

2.线程操作完毕之后,返回值。

 

WebServicesTask类的代码如下:

public class WebServicesTask extends AsyncTask<String,Integer,String>{private Context mContext ;public WebServicesTask(){//nothing to do}@Overrideprotected void onPreExecute(){//nothing to do}@Overrideprotected String doInBackground(String... params) {return requestServer(params[0]) ;//返回webServices请求的值。}    @Overrideprotected void onProgressUpdate(Integer... progress) {//nothing to do        }@Overrideprotected void onPostExecute(String result) {//nothing to do}}


 


至此android请求webServices,异步操作,现场返回,介绍完毕。代码部分是我自己手动输入的。如果有任何错误,请留言指出,希望大家共同讨论。相互学习。谢谢!!!

 

原创粉丝点击