zoukankan      html  css  js  c++  java
  • 【转载】Android通过ksoap2调用.net(c#)的webservice

    转载自:http://www.cnblogs.com/badtree/articles/3242842.html

    ■下载 ksoap2-android 包

    http://code.google.com/p/ksoap2-android/wiki/HowToUse?tm=2下载最新版的“ksoap2-android”,我现时使用的版本为:“ksoap2-android-assembly-3.0.0-RC.4-jar-with-dependencies.jar”

    ■引用包

    下载後,将类库复制到“libs” 文件下。如果Eclipse的童鞋到这里引用就完事了,但於Android Studio的就还没有完,因为Android Studio使用的是gradle,故还需要对引用进行声明。找到build.gradle文件(於项目的底部),打开於dependencies节点里,添加代码:

    dependencies {
        compile 'com.android.support:support-v4:13.0.+'
        
       //添加以下代码以声明类库的引用
        compile files('libs/ksoap2-android-assembly-3.0.0-RC.4-jar-with-dependencies.jar')
    }

    下面开始我以一个登录的例子来讲解整个webserive的调用过程
    layout_login中有两个EditText控件,一个按钮,登录界面最基本的配置。

    复制代码
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:gravity="center|center_horizontal|center_vertical"
                  android:orientation="vertical"
                  android:background="#6AA7D2">
    
        <LinearLayout
                android:id="@+id/Layout_Input"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="15dp"
                android:layout_marginBottom="0dp"
                android:orientation="vertical">
    
            <EditText
                    android:id="@+id/Txt_Name"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="text"
                    android:hint="用户名" />
    
            <EditText
                    android:id="@+id/Txt_Password"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="textPassword"
                    android:hint="密码" />
        </LinearLayout>
    
        <LinearLayout
                android:id="@+id/Layout_Button"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp">
    
            <Button
                    android:id="@+id/Btn_Login"
                    android:layout_weight="1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="登录"
                    android:onClick="Btn_Login_OnClick" />
    
        </LinearLayout>
    
    </LinearLayout>
    复制代码

    当点击登录Button时,执行以下事件 

    复制代码
    public void Btn_Login_OnClick(View view) {
            loginName = ControlHelper.GetText(this, R.id.Txt_Name);
            loginPassword = ControlHelper.GetText(this, R.id.Txt_Password);
    
            if (loginName.equals("")) {
                MessageHelper.AlertDialog(this, "操作提示","用户名不能为空."));
                findViewById(R.id.Txt_Name).requestFocus();
                return;
            }
    view.setEnabled(
    false); progressDialog = ProgressDialog.show(this,"Loading...","Please wait...",true,false); Thread thread = new Thread(new Runnable() { @Override public void run() { SystemClock.sleep(1000); Login(loginName, loginPassword); } }); thread.start(); }
    复制代码

    说明:由於Android4.0以後主线程为了线程安全,访问网络不能由主线程进,只能由子线程访问,另外像.net的winform一样,子线程不能控制UI,所有的UI都必需由主线程控制,所以所有的什麽提示框,等候框都必需同主线程去操作。所以上面的代码中,Login的方法是在新开的子线程中完成的。

    而Runnable就是一个Thread要实现的接口,此接口中有一个run()方法,当线程执行start()方法时,就会自动调用Thread的Runnable接口中的run()方法。所以我们要子线程执行的所有代码都在run()里完成。

    顺带一提的就是,子线程读取UI上控件的值是没有限制的,所以如果想在子程线中读取UI,直接读取就可以了。

    但於子线程又是怎样跟主线程沟通的呢?这就要提到另外两个东东就是Handler跟Message了。

    下面先看一看Login方法里面的代码

    复制代码
    private void Login(String name,String psw)
        {
            Message msg = new Message();
    
            try
            {
           //声明Service的空间命名,.net默认为 http://tempuri.org/
           //第二个参数是要调用的方法 SoapObject so
    = new SoapObject(this.getString(R.string.webservice_namespace), "Login");

            //设置调用Service需要传入的两个参数,闻说参数名可以不正确,但顺序必需要正确 so.addProperty(
    "accountName", name); so.addProperty("password", psw);
           // 设置调用WebService方法的SOAP请求信息,并指定SOAP的版本 SoapSerializationEnvelope envelope
    = new SoapSerializationEnvelope(SoapEnvelope.VER12); envelope.bodyOut = so;

           // 设置是否调用的是dotNet开发的WebService envelope.dotNet
    = true;

           // 设置Service所使用的URL String url
    = this.getString(R.string.webservice_domain) + this.getString(R.string.webservice_url_logic); HttpTransportSE ht = new HttpTransportSE(url); ht.call(null, envelope); if (envelope.getResponse()!=null) {
              //接收返回的对象 SoapObject responseSO
    = (SoapObject)envelope.getResponse(); Boolean succeed = Boolean.parseBoolean(responseSO.getProperty("Succeed").toString()); if(!succeed) { msg.obj = responseSO.getProperty("Message").toString(); msg.what = 0; } else { msg.obj = responseSO.getProperty("ReturnObject"); msg.what = 1; } } } catch (Exception ex) { msg.obj = ex.getMessage(); msg.what = -1; } finally { handler.sendMessage(msg); } }
    复制代码

    我先讲讲我们的ksoap2是如何使用,再去讲解Message与Handler。

    上面的注释都写得很清楚了,在这里我提一提,在获取接收的对象时,有两种方法:

    1. envelope.bodyIn

    2.envelope.getResponse();

    我选用的是第二种方法,因为我发现可以很好转换回一个SoapObject,可能bodyIn都可以,但我没有深入的研究,没有发言权,有兴趣又好学的同学们可以研究一下,记得研究完跟我说一声。

    别外值得一提如果你的Service返回的是一个对象,在ksoap2里,你的对象依然是一个SoapObject,你必须要写代码自已转换,後面我还会有文章另外介绍。

    下面再讲如何,通知主线程,我所获取得的返回结果了,大家看到,於Login方法中一开始就定义了一个Message的对象,其实这个对象就是用於线程之间通讯所使用的,姑且先这样理解。

    他有一个obj的属性与一个what的属性,obj用於存放通讯的数据,what是用於存放一个标志,为什麽需要这个标志呢?因为你Message可能有好多种状态情况,what就是为了区分这些状态而存在,如果你还是有不明白的,可能看了以下的代码,或许会对你的了解有所帮助。

    Handler接收Message

    复制代码
    private Handler handler = new Handler(){
            @Override
            public void handleMessage(Message msg){
                findViewById(R.id.Btn_Login).setEnabled(true);
                progressDialog.dismiss();
                switch (msg.what)
                {
                    case -1:
                        //exception
                        MessageHelper.AlertDialog(Activity_Main.this, "异常提示", msg.obj.toString());
                        break;
                    case 0:
                        //fail
                        MessageHelper.AlertDialog(Activity_Main.this, "错误提示", msg.obj.toString());
                        break;
                    case 1:
                        //login success
                        MessageHelper.AlertDialog(Activity_Main.this, "操作提示", "登录成功。");

                break;

    default: break; } } };
    复制代码

    最後是需要在activity中定义一个Handler对象,并实现handleMessage的方法就可以。这样整个调用Webservice的过程就完成了。

    但是这里面还差一点小小的动作,就是由於你的程序未声明网络访问的权限,所以无法加接网络,并且有异常被抛出,声明方法是,只需要在AndroidManifest.xml中声明就可以了。

    <uses-sdk
            android:minSdkVersion="7"
            android:targetSdkVersion="16" />
    
    <!--添加以下节点声明网络使用-->
    <uses-permission android:name="android.permission.INTERNET" />

    OK,你的调用webservice的程序就可以正常运行了。

  • 相关阅读:
    Android 按键消息处理Android 按键消息处理
    objcopy
    SQLite多线程读写实践及常见问题总结
    android动画坐标定义
    Android动画效果translate、scale、alpha、rotate
    Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类)
    Flatten Binary Tree to Linked List
    Distinct Subsequences
    Populating Next Right Pointers in Each Node II
    Populating Next Right Pointers in Each Node
  • 原文地址:https://www.cnblogs.com/mushishi/p/3426602.html
Copyright © 2011-2022 走看看