【问题标题】:Ksoap2 is not working in android 3.0 getting NetworkOnMainThreadExceptionKsoap2 在获取 NetworkOnMainThreadException 的 android 3.0 中不起作用
【发布时间】:2013-05-10 21:56:06
【问题描述】:

Ksoap2 在 Android 3.0 中无法运行。 Logcat 显示 NetworkOnMainThreadException:

02-24 20:18:34.536: ERROR/AndroidRuntime(428): java.lang.RuntimeException: Unable to start activity ComponentInfo{com. Bill/com. Bill.Diag}: android.os.NetworkOnMainThreadException
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1701)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1717)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at android.app.ActivityThread.access$1500(ActivityThread.java:123)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:984)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at android.os.Looper.loop(Looper.java:126)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at android.app.ActivityThread.main(ActivityThread.java:3900)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at java.lang.reflect.Method.invokeNative(Native Method)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at java.lang.reflect.Method.invoke(Method.java:491)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at dalvik.system.NativeStart.main(Native Method)
02-24 20:18:34.536: ERROR/AndroidRuntime(428): Caused by: android.os.NetworkOnMainThreadException
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1069)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at dalvik.system.BlockGuard$WrappedNetworkSystem.connect(BlockGuard.java:368)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:208)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:431)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at java.net.Socket.connect(Socket.java:901)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.<init>(HttpConnection.java:75)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.<init>(HttpConnection.java:48)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection$Address.connect(HttpConnection.java:304)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnectionPool.get(HttpConnectionPool.java:89)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getHttpConnection(HttpURLConnectionImpl.java:292)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.makeConnection(HttpURLConnectionImpl.java:274)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:217)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at org.ksoap2.transport.ServiceConnectionSE.connect(ServiceConnectionSE.java:46)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:68)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at com.IsBill.Connection.Connect(Connection.java:53)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at com.IsBill.Diagnos.FirstProv(Diagnos.java:385)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at com.IsBill.Diagnos.onCreate(Diagnos.java:53)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1665)
02-24 20:18:34.536: ERROR/AndroidRuntime(428):     ... 11 more

【问题讨论】:

  • 阅读here 了解NetworkOnMainThreadException
  • 您可以将您的 ksoap 调用包装在 AsyncTask 中。阅读here了解更多信息。
  • 您认为 ksoap 不起作用的结论是错误的。 UI 线程上的任何网络流量都将显示相同的行为。

标签: android ksoap2 android-strictmode


【解决方案1】:

在 HoneyComb 中启用了 StrictMode,禁用它以避免NetworkOnMainThreadException

    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);

更新:

使用 StrictModeWrapper 类检测是否存在 strictMode 的其他方式。

 private static boolean strictModeAvailable;

    // use the StrictModeWrapper to see if we are running on Android 2.3 or higher and StrictMode is available
    static {
        try {
            StrictModeWrapper.checkAvailable();
            strictModeAvailable = true;
        } catch (Throwable throwable) {
            strictModeAvailable = false;
        }
    }

StrictModeWrapper 类

import android.os.StrictMode;

/**
 * StrictModeWrapper is a wrapper class for the android class android.os.StrictMode provided with Android 2.3 onwards.
 * It allows usage of StrictMode class on devices/emulators with Android 2.3 or higher, while providing an availability
 * check so that the code can stay in situ for lower platform versions. See the application class for usage.
 *
 * @author Manfred Moser <manfred@simpligility.com>
 *
 * @see "http://android-developers.blogspot.com/2009/04/backward-compatibility-for-android.html"
 * @see "http://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html"
 */
public class StrictModeWrapper {

    /* class initialization fails when this throws an exception */
   static {
       try {
           Class.forName("android.os.StrictMode", true, Thread.currentThread().getContextClassLoader());
       } catch (Exception ex) {
           throw new RuntimeException(ex);
       }
   }

    /**
     * Check if the class android.os.StrictMode is available at runtime.
     */
   public static void checkAvailable() {}


    /**
     * Call StrictMode.enableDefaults().
     */
    public static void enableDefaults() {
       StrictMode.enableDefaults();
    }

    // all the implementation below is not tested but it should work ... feel free to check and send me fixes..
    public static  void setThreadPolicy(android.os.StrictMode.ThreadPolicy policy) {
        StrictMode.setThreadPolicy(policy);
    }


    public static  android.os.StrictMode.ThreadPolicy getThreadPolicy() {
        return StrictMode.getThreadPolicy();
    }

    public static  android.os.StrictMode.ThreadPolicy allowThreadDiskWrites() {
        return StrictMode.allowThreadDiskWrites();
    }

    public static  android.os.StrictMode.ThreadPolicy allowThreadDiskReads() {
        return StrictMode.allowThreadDiskReads();
    }

    public static  void setVmPolicy(android.os.StrictMode.VmPolicy policy) {
        StrictMode.setVmPolicy(policy);
    }

    public static android.os.StrictMode.VmPolicy getVmPolicy() {
        return StrictMode.getVmPolicy();
    }

    public static final class ThreadPolicyWrapper
    {
        public static final class BuilderWrapper
        {
            StrictMode.ThreadPolicy.Builder builderInstance;

            public  BuilderWrapper() {
                    builderInstance = new StrictMode.ThreadPolicy.Builder();
            }

            public  BuilderWrapper(android.os.StrictMode.ThreadPolicy policy) {
                    builderInstance = new StrictMode.ThreadPolicy.Builder(policy);
            }

            public android.os.StrictMode.ThreadPolicy.Builder detectAll() {
                return builderInstance.detectAll();
            }

            public android.os.StrictMode.ThreadPolicy.Builder permitAll() {
                return builderInstance.permitAll();
            }

            public android.os.StrictMode.ThreadPolicy.Builder detectNetwork() {
                return builderInstance.detectNetwork();
            }

            public android.os.StrictMode.ThreadPolicy.Builder permitNetwork() {
                return builderInstance.permitNetwork();
            }

            public android.os.StrictMode.ThreadPolicy.Builder detectDiskReads() {
                return builderInstance.detectDiskReads();
            }

            public android.os.StrictMode.ThreadPolicy.Builder permitDiskReads() {
                return builderInstance.permitDiskReads();
            }

            public android.os.StrictMode.ThreadPolicy.Builder detectDiskWrites() {
                return builderInstance.detectDiskWrites();
            }

            public android.os.StrictMode.ThreadPolicy.Builder permitDiskWrites() {
                return builderInstance.permitDiskWrites();
            }

            public android.os.StrictMode.ThreadPolicy.Builder penaltyDialog() {
                return builderInstance.penaltyDialog();
            }

            public android.os.StrictMode.ThreadPolicy.Builder penaltyDeath() {
                return builderInstance.penaltyDeath();
            }

            public android.os.StrictMode.ThreadPolicy.Builder penaltyLog() {
                return builderInstance.penaltyLog();
            }

            public android.os.StrictMode.ThreadPolicy.Builder penaltyDropBox() {
                return builderInstance.penaltyDropBox();
            }

            public android.os.StrictMode.ThreadPolicy build() {
                return builderInstance.build();
            }
        }
    }

    public static final class VmPolicyWrapper {
        public static final class BuilderWrapper {
            private StrictMode.VmPolicy.Builder builderInstance;

            public BuilderWrapper() {
                builderInstance = new StrictMode.VmPolicy.Builder();
            }

            public android.os.StrictMode.VmPolicy.Builder detectAll() {
                return builderInstance.detectAll();
            }

            public android.os.StrictMode.VmPolicy.Builder detectLeakedSqlLiteObjects() {
                return builderInstance.detectLeakedSqlLiteObjects();
            }

            public android.os.StrictMode.VmPolicy.Builder penaltyDeath() {
                return builderInstance.penaltyDeath();
            }

            public android.os.StrictMode.VmPolicy.Builder penaltyLog() {
                return builderInstance.penaltyLog();
            }

            public android.os.StrictMode.VmPolicy.Builder penaltyDropBox() {
                return builderInstance.penaltyDropBox();
            }

            public android.os.StrictMode.VmPolicy build() {
                return builderInstance.build();
            }
        }
    }
    // add more wrapping as desired..
}

【讨论】:

  • 正确 .. 和 ICS。这取决于硬件制造商是否允许该设置。默认情况下,他们可能不会,因为上游就是这样。无论如何......这充其量是一种解决方法。只做一个异步任务。
【解决方案2】:

您需要在单独的线程中而不是在 UI 线程中执行任何网络操作。最简单的方法是使用 AsyncTask。

【讨论】:

    【解决方案3】:

    网络操作必须在新线程上处理才能这样做
    您应该在 AsyncTask 任务类中调用 ksoap 请求 在您的 Asynctask 中调用您的 KSOAP reuest doInBackground() 方法
    例如

    public class Get extends AsyncTask<Void, Void, String> {
    @Override
    protected String doInBackground(Void... arg) {
    
       //your KSOAP request code
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-10
      相关资源
      最近更新 更多