当前位置: 首页 > news >正文

Android平台调用Web Service:螺纹的引入

文字连接

剩下的问题

MainActivity的onCreate方法中假设没有有这段代码:

// 强制在UI线程中操作
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
       .detectDiskReads().detectDiskWrites().detectNetwork()
        .penaltyLog().build());
           
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
       .detectLeakedSqlLiteObjects().penaltyLog().penaltyDeath()
        .build());

 

会报错误例如以下:

FATAL EXCEPTION:main

java.lang.NullPointerException

atcom.example.demoservice.MainActivity.getRemoteInfo(MainActivity.java:91)

atcom.example.demoservice.MainActivity$1.onClick(MainActivity.java:51)

 

这是由于android 3.0+以上 已经不建议在activity中加入耗时操作,要界面和数据脱离。4.0以上的通信都必须放到线程里去做不能在UI线程。解决的方法另起线程假设一定要想在UI线程操作,就须要加入如代码

 

显然这样做是不可取的,由于通信消耗时间长,可能会让用户傻傻的等待。那么接下来就通过引入线程来解决问题。


通过Runnable接口和Thread类创建线程

我们能够用Runnable接口和Thread类创建线程。从而舍弃强制使用UI主线程的方式,代码例如以下(同一时候对代码进行了整理,把nameSpace等变量抽出来)

public classMainActivity extends Activity { 
 
    public static final String TAG ="webService_pj";
   
    private EditText phoneSecEditText; 
    private TextView resultView; 
    private Button queryButton; 
 
    @Override 
    public void onCreate(BundlesavedInstanceState) { 
           
//           StrictMode.setThreadPolicy(newStrictMode.ThreadPolicy.Builder()
//       .detectDiskReads().detectDiskWrites().detectNetwork()
//        .penaltyLog().build());
//           
//    StrictMode.setVmPolicy(newStrictMode.VmPolicy.Builder()
//       .detectLeakedSqlLiteObjects().penaltyLog().penaltyDeath()
//        .build());
   
       super.onCreate(savedInstanceState); 
       setContentView(R.layout.activity_main); 
 
        phoneSecEditText = (EditText)findViewById(R.id.phone_sec); 
        resultView = (TextView)findViewById(R.id.result_text); 
        queryButton = (Button)findViewById(R.id.query_btn); 
 
        queryButton.setOnClickListener(newOnClickListener() { 
            @Override 
            public void onClick(View v) { 
         
                   Log.i(TAG,"MainActivity线程ID:"+Thread.currentThread().getId());
 
                // 手机号码(段) 
                String phoneSec =phoneSecEditText.getText().toString().trim(); 
                // 简单推断用户输入的手机号码(段)是否合法 
                if("".equals(phoneSec) || phoneSec.length() < 7) { 
                    // 给出错误提示 
                   phoneSecEditText.setError("您输入的手机号码(段)有误!"); 
                   phoneSecEditText.requestFocus(); 
                    // 将显示查询结果的TextView清空 
                   resultView.setText(""); 
                    return; 
                } 
               
                // 命名空间 
                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";
                // method params and values
                ArrayList<String> params= new ArrayList<String>();
                ArrayList<Object> vals =new ArrayList<Object>();
               params.add("mobileCode");
                params.add("userId");
                vals.add(phoneSec);
                vals.add("");
               
                // 通过Runnable接口和Thread类 创建线程调用WebService
                   newMyThread(nameSpace,methodName,endPoint,soapAction,
                                                           params,vals).start();
                       //将WebService返回的结果显示在TextView中 
                   resultView.setText(getResult());
 
            } 
        }); 
    } 
 
 
  
   
//通过Runnable接口和Thread类,得到线程返回值
privateString result;
 
publicString getResult(){
returnresult;
}
 
    private class MyThread extends Thread
{
 
    private String nameSpace;
    private String methodName;
    private String endPoint;
    private String soapAction;
        private ArrayList<String> params;
        private ArrayList<Object> vals;
       
    public MyThread(String nameSpace,  String methodName,
                   StringendPoint, String soapAction, ArrayList<String> params,ArrayList<Object> vals){ 
        this.nameSpace = nameSpace;
        this.methodName = methodName;
        this.endPoint = endPoint;
        this.soapAction = soapAction;
        this.params = params;
        this.vals = vals;
    } 
   
@Override
publicvoid run()
{
Log.i(TAG,"MyService线程ID:"+Thread.currentThread().getId());
result= getRemoteInfo(nameSpace, methodName, endPoint,
                                soapAction,params,vals);
}
 
}
   
      
    /**
     *@MethodName        : getRemoteInfo
     *@Description        : 调用远程webservice方法
     * @param nameSpace
     * @param methodName
     * @param endPoint
     * @param soapAction
     * @param params
     * @param vals
     * @return
     */
    public String getRemoteInfo(StringnameSpace,  String methodName,
                                   StringendPoint, String soapAction, ArrayList<String> params,
                                   ArrayList<Object>vals) { 
 
 
        // 指定WebService的命名空间和调用的方法名 
        SoapObject rpc = newSoapObject(nameSpace, methodName); 
 
        //设置需调用WebService接口须要传入的两个參数mobileCode、userId 
        for (int i = 0; i < params.size();i++) {
rpc.addProperty(params.get(i),vals.get(i));
}
 
 
        //生成调用WebService方法的SOAP请求信息,并指定SOAP的版本号 
        SoapSerializationEnvelope envelope =new SoapSerializationEnvelope(SoapEnvelope.VER10); 
 
        envelope.bodyOut = rpc; 
        // 设置是否调用的是dotNet开发的WebService 
//        envelope.dotNet = true; 
        // 等价于envelope.bodyOut = rpc; 
        envelope.setOutputSoapObject(rpc); 
 
        HttpTransportSE transport = newHttpTransportSE(endPoint); 
        try { 
            // 调用WebService 
            transport.call(soapAction,envelope); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
 
        // 获取返回的数据 
        SoapObject object = (SoapObject)envelope.bodyIn; 
       
        String result = "";
        if (object != null) {
               // 获取返回的结果 
               result =object.getProperty(0).toString(); 
        }
 
        return result;
    } 
} 


 

通过线程进行通信。得到相同结果



出现新的问题

能够发现,运行线程中须要在线程中返回一个值,通过在run()中保存返回值。存储返回值的变量应该是MainActivity的成员变量。然后在主线程中用一个get方法取得该值。

可是run何时完毕是未知的。非常可能当第一次点击button后。依旧看不到结果,直到第二次或者很多其它才看到,所以我们须要一定的机制来保证。

 

而在Java se5就開始用Callable和Future来管理多线程了。能够解决问题。接下文。。


源代码下载

http://download.csdn.net/detail/tcl_6666/7365341


版权声明:本文博客原创文章,博客,未经同意,不得转载。

相关文章:

  • sed去掉文件中的空行
  • 前端手札--meta标记篇
  • 小技巧:Windows Server 2012R2 WiFi 无法连接问题
  • 在项目中引入领域驱动设计的经验
  • 【零基础学习iOS开发】【02-C语言】11-函数的声明和定义
  • 树莓派 安装 php
  • 互联网架构设想的大型应用软件,并建议
  • Android软硬整合技术(HALFramework)
  • httpry 升级版本 secihttp 发布了
  • 认为最重要的是:不要说自己正在「创业」(转)
  • 第一章 词汇陷阱
  • 在我的眼里,生产主管(1)——如何做竞争分析
  • Linux用户和组管理
  • Intellij idea 与 eclipse 常用快捷键对比(Shortcuts to compare : Intellij idea VS Eclipse)
  • 银行之前的转账和支付宝银行间的转账
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • es6要点
  • js正则,这点儿就够用了
  • leetcode-27. Remove Element
  • maya建模与骨骼动画快速实现人工鱼
  • Node项目之评分系统(二)- 数据库设计
  • SQL 难点解决:记录的引用
  • SQLServer之索引简介
  • WePY 在小程序性能调优上做出的探究
  • 回流、重绘及其优化
  • 记录一下第一次使用npm
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 实现菜单下拉伸展折叠效果demo
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 数组大概知多少
  • 优化 Vue 项目编译文件大小
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • 说说我为什么看好Spring Cloud Alibaba
  • ​queue --- 一个同步的队列类​
  • ###C语言程序设计-----C语言学习(6)#
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (排序详解之 堆排序)
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (五)Python 垃圾回收机制
  • (转)编辑寄语:因为爱心,所以美丽
  • (转)平衡树
  • .NET简谈设计模式之(单件模式)
  • .net经典笔试题
  • @开发者,一文搞懂什么是 C# 计时器!
  • [C]整形提升(转载)
  • [c++] C++多态(虚函数和虚继承)
  • [iOS]把16进制(#871f78)颜色转换UIColor
  • [MySQL]日期和时间函数
  • [nowCoder] 两个不等长数组求第K大数
  • [Oh My C++ Diary]用cout输出时后endl的使用
  • [one_demo_10]递归解决汉诺塔问题
  • [paddle]ModuleNotFoundError: No module named ‘paddle.nn.layer.layers