如何解决android.os.NetworkOnMainThreadException?

时间:2014-05-24 01:13:01

标签: java c# android ksoap2

我正在使用4.0.3目标,而我正在使用kso​​ap2。 Web服务是Visual Studio 2010 Express的WCF。

可能是soap_action,call或namespace的错误。

我每次都会收到下一个错误

05-24 02:49:42.738: W/System.err(5231): android.os.NetworkOnMainThreadException
05-24 02:49:42.748: W/System.err(5231):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1154)
05-24 02:49:42.748: W/System.err(5231):     at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
05-24 02:49:42.748: W/System.err(5231):     at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
05-24 02:49:42.748: W/System.err(5231):     at java.net.InetAddress.getAllByName(InetAddress.java:214)
05-24 02:49:42.748: W/System.err(5231):     at com.android.okhttp.internal.Dns$1.getAllByName(Dns.java:28)
05-24 02:49:42.748: W/System.err(5231):     at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:216)
05-24 02:49:42.748: W/System.err(5231):     at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:122)
05-24 02:49:42.748: W/System.err(5231):     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:292)
05-24 02:49:42.748: W/System.err(5231):     at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
05-24 02:49:42.748: W/System.err(5231):     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
05-24 02:49:42.748: W/System.err(5231):     at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
05-24 02:49:42.748: W/System.err(5231):     at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:89)
05-24 02:49:42.748: W/System.err(5231):     at org.ksoap2.transport.ServiceConnectionSE.connect(ServiceConnectionSE.java:46)
05-24 02:49:42.748: W/System.err(5231):     at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:68)
05-24 02:49:42.748: W/System.err(5231):     at org.tempuri.IAndroid.getAllProductsAndOffers(IAndroid.java:29)
05-24 02:49:42.748: W/System.err(5231):     at info.android.MapaFragment.GetData(MapaFragment.java:78)
05-24 02:49:42.748: W/System.err(5231):     at info.android.MapaFragment.onCreateView(MapaFragment.java:64)
05-24 02:49:42.748: W/System.err(5231):     at android.app.Fragment.performCreateView(Fragment.java:1700)
05-24 02:49:42.748: W/System.err(5231):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:894)
05-24 02:49:42.748: W/System.err(5231):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1066)
05-24 02:49:42.748: W/System.err(5231):     at android.app.BackStackRecord.run(BackStackRecord.java:684)
05-24 02:49:42.748: W/System.err(5231):     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1455)
05-24 02:49:42.748: W/System.err(5231):     at android.app.FragmentManagerImpl$1.run(FragmentManager.java:447)
05-24 02:49:42.748: W/System.err(5231):     at android.os.Handler.handleCallback(Handler.java:733)
05-24 02:49:42.748: W/System.err(5231):     at android.os.Handler.dispatchMessage(Handler.java:95)
05-24 02:49:42.748: W/System.err(5231):     at android.os.Looper.loop(Looper.java:212)
05-24 02:49:42.748: W/System.err(5231):     at android.app.ActivityThread.main(ActivityThread.java:5151)
05-24 02:49:42.748: W/System.err(5231):     at java.lang.reflect.Method.invokeNative(Native Method)
05-24 02:49:42.748: W/System.err(5231):     at java.lang.reflect.Method.invoke(Method.java:515)
05-24 02:49:42.748: W/System.err(5231):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
05-24 02:49:42.748: W/System.err(5231):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
05-24 02:49:42.748: W/System.err(5231):     at dalvik.system.NativeStart.main(Native Method)

我的wsdl是:

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" name="Android" targetNamespace="http://tempuri.org/">
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://localhost:52604/Android.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="http://localhost:52604/Android.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
<xsd:import schemaLocation="http://localhost:52604/Android.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/Android"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="IAndroid_EnviarCorreo_InputMessage">
<wsdl:part name="parameters" element="tns:EnviarCorreo"/>
</wsdl:message>
<wsdl:message name="IAndroid_EnviarCorreo_OutputMessage">
<wsdl:part name="parameters" element="tns:EnviarCorreoResponse"/>
</wsdl:message>
<wsdl:message name="IAndroid_UserPasswordExists_InputMessage">
<wsdl:part name="parameters" element="tns:UserPasswordExists"/>
</wsdl:message>
<wsdl:message name="IAndroid_UserPasswordExists_OutputMessage">
<wsdl:part name="parameters" element="tns:UserPasswordExistsResponse"/>
</wsdl:message>
<wsdl:message name="IAndroid_UserExists_InputMessage">
<wsdl:part name="parameters" element="tns:UserExists"/>
</wsdl:message>
<wsdl:message name="IAndroid_UserExists_OutputMessage">
<wsdl:part name="parameters" element="tns:UserExistsResponse"/>
</wsdl:message>
<wsdl:message name="IAndroid_getAllProductsAndOffers_InputMessage">
<wsdl:part name="parameters" element="tns:getAllProductsAndOffers"/>
</wsdl:message>
<wsdl:message name="IAndroid_getAllProductsAndOffers_OutputMessage">
<wsdl:part name="parameters" element="tns:getAllProductsAndOffersResponse"/>
</wsdl:message>
<wsdl:message name="IAndroid_getProductByOffer_InputMessage">
<wsdl:part name="parameters" element="tns:getProductByOffer"/>
</wsdl:message>
<wsdl:message name="IAndroid_getProductByOffer_OutputMessage">
<wsdl:part name="parameters" element="tns:getProductByOfferResponse"/>
</wsdl:message>
<wsdl:message name="IAndroid_BuyProductOrOffer_InputMessage">
<wsdl:part name="parameters" element="tns:BuyProductOrOffer"/>
</wsdl:message>
<wsdl:message name="IAndroid_BuyProductOrOffer_OutputMessage">
<wsdl:part name="parameters" element="tns:BuyProductOrOfferResponse"/>
</wsdl:message>
<wsdl:message name="IAndroid_SetFavouriteOff_InputMessage">
<wsdl:part name="parameters" element="tns:SetFavouriteOff"/>
</wsdl:message>
<wsdl:message name="IAndroid_SetFavouriteOff_OutputMessage">
<wsdl:part name="parameters" element="tns:SetFavouriteOffResponse"/>
</wsdl:message>
<wsdl:message name="IAndroid_SetFavouriteOn_InputMessage">
<wsdl:part name="parameters" element="tns:SetFavouriteOn"/>
</wsdl:message>
<wsdl:message name="IAndroid_SetFavouriteOn_OutputMessage">
<wsdl:part name="parameters" element="tns:SetFavouriteOnResponse"/>
</wsdl:message>
<wsdl:portType name="IAndroid">
<wsdl:operation name="EnviarCorreo">
<wsdl:input wsaw:Action="http://tempuri.org/IAndroid/EnviarCorreo" message="tns:IAndroid_EnviarCorreo_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IAndroid/EnviarCorreoResponse" message="tns:IAndroid_EnviarCorreo_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="UserPasswordExists">
<wsdl:input wsaw:Action="http://tempuri.org/IAndroid/UserPasswordExists" message="tns:IAndroid_UserPasswordExists_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IAndroid/UserPasswordExistsResponse" message="tns:IAndroid_UserPasswordExists_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="UserExists">
<wsdl:input wsaw:Action="http://tempuri.org/IAndroid/UserExists" message="tns:IAndroid_UserExists_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IAndroid/UserExistsResponse" message="tns:IAndroid_UserExists_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="getAllProductsAndOffers">
<wsdl:input wsaw:Action="http://tempuri.org/IAndroid/getAllProductsAndOffers" message="tns:IAndroid_getAllProductsAndOffers_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IAndroid/getAllProductsAndOffersResponse" message="tns:IAndroid_getAllProductsAndOffers_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="getProductByOffer">
<wsdl:input wsaw:Action="http://tempuri.org/IAndroid/getProductByOffer" message="tns:IAndroid_getProductByOffer_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IAndroid/getProductByOfferResponse" message="tns:IAndroid_getProductByOffer_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="BuyProductOrOffer">
<wsdl:input wsaw:Action="http://tempuri.org/IAndroid/BuyProductOrOffer" message="tns:IAndroid_BuyProductOrOffer_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IAndroid/BuyProductOrOfferResponse" message="tns:IAndroid_BuyProductOrOffer_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="SetFavouriteOff">
<wsdl:input wsaw:Action="http://tempuri.org/IAndroid/SetFavouriteOff" message="tns:IAndroid_SetFavouriteOff_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IAndroid/SetFavouriteOffResponse" message="tns:IAndroid_SetFavouriteOff_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="SetFavouriteOn">
<wsdl:input wsaw:Action="http://tempuri.org/IAndroid/SetFavouriteOn" message="tns:IAndroid_SetFavouriteOn_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IAndroid/SetFavouriteOnResponse" message="tns:IAndroid_SetFavouriteOn_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BasicHttpBinding_IAndroid" type="tns:IAndroid">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="EnviarCorreo">
<soap:operation soapAction="http://tempuri.org/IAndroid/EnviarCorreo" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="UserPasswordExists">
<soap:operation soapAction="http://tempuri.org/IAndroid/UserPasswordExists" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="UserExists">
<soap:operation soapAction="http://tempuri.org/IAndroid/UserExists" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAllProductsAndOffers">
<soap:operation soapAction="http://tempuri.org/IAndroid/getAllProductsAndOffers" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getProductByOffer">
<soap:operation soapAction="http://tempuri.org/IAndroid/getProductByOffer" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="BuyProductOrOffer">
<soap:operation soapAction="http://tempuri.org/IAndroid/BuyProductOrOffer" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SetFavouriteOff">
<soap:operation soapAction="http://tempuri.org/IAndroid/SetFavouriteOff" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SetFavouriteOn">
<soap:operation soapAction="http://tempuri.org/IAndroid/SetFavouriteOn" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Android">
<wsdl:port name="BasicHttpBinding_IAndroid" binding="tns:BasicHttpBinding_IAndroid">
<soap:address location="http://localhost:52604/Android.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

我的请求xml是:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IAndroid/getAllProductsAndOffers</Action>
  </s:Header>
  <s:Body>
    <getAllProductsAndOffers xmlns="http://tempuri.org/">
      <province_id>0</province_id>
      <city_id>0</city_id>
      <code i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
      <favoritos i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
      <tipo i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
    </getAllProductsAndOffers>
  </s:Body>
</s:Envelope>

我的配置类:

package org.tempuri;


/**
 * Class to configure remote host.
 *
 */
public final class Configuration {

    /**
     * Prohibits instantiation.
     */
    private Configuration(){
    }

    /**
     * URL.
     */

    private static String NAMESPACE = "http://tempuri.org/";    
    private static String wsUrl = "http://localhost:52604/Android.svc?Wsdl";

    /**
     * Configures address of web service, for example
     * <tt>http://localhost:8080/Ws2Ksoap/services/HelloWorld</tt>.
     *
     * @param wsUrl
     *              The address to access to web service.
     */
    public static void setConfiguration(final String wsUrl) {
        if (wsUrl != null) {
            Configuration.wsUrl = wsUrl;
        }
    }

    /**
     *
     * @return The address which the web service is deployed.
     */
    public static String getWsUrl() {
        return wsUrl;
    }

    public static String getWsNameSpace() {
        return NAMESPACE;
    }
}

IAndroid类:

package org.tempuri

public class IAndroid {

...
    public  WcfResponsePOList getAllProductsAndOffers(java.lang.Integer province_id, java.lang.Integer city_id, java.lang.String code, java.lang.String favoritos, java.lang.String tipo) throws Exception {
        String METHOD_NAME = "getAllProductsAndOffers";

        SoapObject _client = new SoapObject(Configuration.getWsNameSpace(), METHOD_NAME);

        _client.addProperty("province_id", province_id);
        _client.addProperty("city_id", city_id);
        _client.addProperty("code", code);
        _client.addProperty("favoritos", favoritos);
        _client.addProperty("tipo", tipo);

        SoapSerializationEnvelope _envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);

        _envelope.dotNet = true;

        _envelope.bodyOut = _client;

        AndroidHttpTransport _ht = new AndroidHttpTransport(Configuration.getWsUrl());

        _ht.call(Configuration.getWsNameSpace() + METHOD_NAME, _envelope);

        SoapObject _ret = (SoapObject) _envelope.getResponse();
        int _len = _ret.getPropertyCount();


        WcfResponsePOList _returned = new WcfResponsePOList();

        for (int _i = 0; _i < _len; _i++) {
            _returned.setProperty(_i, _ret.getProperty(_i));        
        }

        return _returned;
    }
...
}

我的清单文件

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.android"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="16" />

    <permission
        android:name="info.android.permission.MAPS_RECEIVE"
        android:protectionLevel="signature" />

    <uses-permission android:name="info.android.permission.MAPS_RECEIVE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />    
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>

    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >



        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="XXXXXXXXXXXXXXXXXXXXXXXXXX" />

        <meta-data android:name="com.google.android.gms.version" android:value="4323000" />

        <activity
            android:name="info.android.MainActivity"
            android:label="@string/app_name" >

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


    </application>



</manifest>

为什么我收到此错误?

2 个答案:

答案 0 :(得分:4)

将此代码用于活动

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy =
       new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

答案 1 :(得分:2)

Android OS不允许在主线程/ UI线程中执行繁重的进程,因为应用程序将减速,降低性能并且应用程序将滞后。

但是,您可以在AsyncTask中执行它,如下所示。在您的asyncTask的doInBackground中执行您的过程/调用您的函数。

private class Download extends AsyncTask<String, Void, String> {
    ProgressDialog pDialog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.d("Hi", "Download Commencing");

        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("Downloading Database...");


        String message= "Executing Process";

        SpannableString ss2 =  new SpannableString(message);
        ss2.setSpan(new RelativeSizeSpan(2f), 0, ss2.length(), 0);  
        ss2.setSpan(new ForegroundColorSpan(Color.BLACK), 0, ss2.length(), 0); 

        pDialog.setMessage(ss2);

        pDialog.setCancelable(false);
        pDialog.show();
    }

    @Override
    protected String doInBackground(String... params) {

        //INSERT YOUR FUNCTION CALL HERE

        return "Executed!";

    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Log.d("Hi", "Done Downloading.");
        pDialog.dismiss();

    }
}

并将其称为:new Download().execute("");来自另一个函数。

您可以取消进度对话框。我个人喜欢它,因为我知道我的进程将在用户可以执行任何操作之前完成(如数据加载),确保在用户与程序交互时不会发生错误。