Android调用WebService过程中遇到的一些问题及解决方法

  公司之前主要推出的是WindowsMobile设备的终端,我学的.net还可以用的上,可以在上面做一些简单的应用程序开发 ,但现在公司主推Android系统的终端了!我不得不也要学习Android,要不然我就在这呆不下去了...

  好了,进入正题,Android的开发环境ADT我就不多说了(不知道的可以Google)。

  参考博客:http://blog.csdn.net/lyq8479/article/details/6428288

  在Android平台调用Web Service需要依赖于第三方类库ksoap2. 它的下载地址是:http://code.google.com/p/ksoap2-android/

  一、准备工作

  新Android项目,把刚才下载的ksoap2包放在项目中的libs目录下,刷新项目点击ksoap2包右键,选择Build Path>Add to Build Path 好了。

  这时显示的可视化界面效果如图:

如果视图显示一片空白(没有可视化界面)请关闭ADT,移除项目空间下\.metadata\.plugins\org.eclipse.e4.workbench\workbench.xmi文件重新打开eclipse.

  右键项目运行-选择Android Application项目,会自己运行模拟器,如果提示“Failed to initialize Monitor Thread: Unable to establish loopback connection”错误。

 

Google一下发现这个问题很常见,有关闭Adb进程再开启,关闭防火墙,重启电脑或eclipse。我的关闭防火墙OK了(电脑上安的是小a,把它禁止1小时)。重启eclipse就可以在模拟器中运行了。如果Android SDK Manager中有更新请完成这些更新,有时它也会影响。

  二、编写布局文件res/layout/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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/phonenumber" />

    <EditText
        android:id="@+id/phone_sec"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/textView1"
        android:ems="10"
        android:hint="1234567"
        android:inputType="number"
        android:singleLine="true" >

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/btn_query"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/phone_sec"
        android:layout_below="@+id/phone_sec"
        android:text="@string/query" />

    <TextView
        android:id="@+id/txt_result"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/btn_query"
        android:layout_below="@+id/btn_query"/>

</RelativeLayout>

我是第一次使用eclipse开发Android项目,很多小问题都不知道怎么回事,比如自己写了一个Button 照着它自带的TextView写了一个android:text="@string/query",在一直显示有错误,如果把@string/去掉,没有错误还有警告!后来在老朋友的帮助下才明白,如果那样写“query”根当于使用了一个变量但我又没有声明,所以显示错误,需要在/res/values/strings.xml中声明这个变量就行了。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">WSTest</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="phonenumber">phonenumber:</string>
    <string name="query">query</string>
</resources>

三、编写MainActivity类

package com.example.wstest;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.transport.HttpTransportSE;

public class MainActivity extends Activity {
    
    private EditText phoneSecEditText;  
    private TextView resultView;  
    private Button queryButton;
    
    private ProgressDialog dialog;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //自己的代码
        phoneSecEditText = (EditText) findViewById(R.id.phone_sec);
        resultView = (TextView) findViewById(R.id.txt_result);  
        queryButton = (Button) findViewById(R.id.btn_query);
        dialog = new ProgressDialog(this);
        dialog .setTitle("提示");
        dialog.setMessage("正在查询,请稍后....");
        
        queryButton.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                //手机号
                String phonesec = phoneSecEditText.getText().toString().trim();
                //判断手机号码是否合法
                if("".equals(phonesec)|| phonesec.length()<7)
                {
                    //给出错误提示
                    phoneSecEditText.setError("您输入的手机号码有误!");
                    phoneSecEditText.requestFocus();
                    //将显示查询结果的TextView清空
                    resultView.setText("");
                    return;
                }
                
                //执行查询
                new MyAsyncTask().execute(phonesec);
                
            }
            
        });
    }
    public class MyAsyncTask extends AsyncTask<String, Void, String>
    {
        //准备
        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
            
            //show dialog
            dialog.show();
        }
        
        //主要执行下载等任务
        @Override
        protected String doInBackground(String... params) {
            // TODO Auto-generated method stub
            //命名空间
            String nameSpace = "http://WebXml.com.cn/";
            //调用的方法名
            String methodName ="getMobileCodeInfo";
            //EndPoint
            String endPoint = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx";
            //SOAP action
            String soapAction = "http://WebXml.com.cn/getMobileCodeInfo";
            
            //指定WebService的命名空间和调用的方法名 
            SoapObject rpc = new SoapObject(nameSpace,methodName);
            
            //设置需调用WebService接口需要传入的两个参数mobileCode、userId  
            rpc.addProperty("mobileCode", params[0]);
            rpc.addProperty("userId","");
            
            //生成调用WebService方法的SOAP请求信息,并指定SOAP的版本  
            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope (SoapEnvelope.VER11);
            envelope.bodyOut= rpc;
            //设置是否调用的是dotNet开发的WebService 
            envelope.dotNet = true;
            //等价于envelope.bodyOut = rpc; 
            //envelope.setOutputSoapObject(rpc);
            
            HttpTransportSE transport = new HttpTransportSE(endPoint);

            try
            {
                //调用 Webservice
                transport.call(soapAction, envelope);
            }
            catch(Exception ex)
            {
                ex.printStackTrace();            
            }
            
            //获取返回的数据
            SoapObject object =(SoapObject) envelope.bodyIn ;
            //获取结果
            String result = object.getProperty(0).toString();
            
            return result;
        }
        
        @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            
            //show getinfo ,close dialog ,clear phonesec
            resultView.setText(result);        
            dialog.dismiss();
            phoneSecEditText.setText("");
        }
        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

  说明:在运行程序的之前必须添加网络授权,双击打开AndroidMainifast.xml文件,选择Permissions->Add->Users Permissioin,然后在右则的Name中选择“android.permission.INTERNET”。

如果没有添加授权,则出出现下面错误:

  四、异步任务

  自从Android3.0之后吧,在UI的主线程中,它是不允许你直接访问网络这种耗时的操作,否则就是出现问题,我第一次做Android开发就照着前人步骤写的,怎么也得不到结果,把我都郁闷坏了,后来才知道需要异步来操作。

  使用比较简单(应该是封装的比较好吧)的AsyncTask异步任务类来完成此操作,自己新建一个类继承于AsyncTask,重写

onPreExecute,doInBackground,onPostExecute这三个方法。onPreExecute是准备工作,doInBackground主要是执行网络连接操作,onPostExecute主要是把异步得到的结果更新到UI主线程上
具体的调用WebService中的方法我就不多说了,网上多的很大同小异,但是调用.net和java的WebService时还是有一点区别的,调用.net WebService时 需要把envelope.dotNet = true;
还有在调用 call方法时,多数是这样调用.net 第一个参数需要,调用java 第一个参数为null,(这个我没有求证,请自己测试)。

 

结果图示:

 

 

 

 

 

 

posted on 2013-11-01 10:22  忽而今夏  阅读(1069)  评论(0编辑  收藏  举报