2014年11月16日日曜日

インターネットアクセスに必要なパーミッションをマニフェストに追加しても例外で落とされてしまいました。

<uses-permission android:name="android.permission.INTERNET" />
ログを見てみると lookupHostByName が AndroidBlockGuardPolicy.onNetwork に違反するように読み取れました。
11-16 18:17:42.834    2279-2279/jp.xxxxxxxx.xxxxxxxx.pingtest E/Trace﹕ error opening trace file: No such file or directory (2)
11-16 18:17:43.154    2279-2279/jp.xxxxxxxx.xxxxxxxx.pingtest I/Choreographer﹕ Skipped 48 frames!  The application may be doing too much work on its main thread.
11-16 18:17:43.174    2279-2279/jp.xxxxxxxx.xxxxxxxx.pingtest D/gralloc_goldfish﹕ Emulator without GPU emulation detected.
11-16 18:17:43.294    2279-2279/jp.xxxxxxxx.xxxxxxxx.pingtest I/Choreographer﹕ Skipped 49 frames!  The application may be doing too much work on its main thread.
11-16 18:17:51.184    2279-2279/jp.xxxxxxxx.xxxxxxxx.pingtest D/AndroidRuntime﹕ Shutting down VM
11-16 18:17:51.184    2279-2279/jp.xxxxxxxx.xxxxxxxx.pingtest W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0xb5f4c288)
11-16 18:17:51.214    2279-2279/jp.xxxxxxxx.xxxxxxxx.pingtest E/AndroidRuntime﹕ FATAL EXCEPTION: main
    android.os.NetworkOnMainThreadException
            at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
            at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
            at java.net.InetAddress.getLocalHost(InetAddress.java:365)
            at jp.xxxxxxxx.xxxxxxxx.pingtest.MainActivity$1.onClick(MainActivity.java:39)
            at android.view.View.performClick(View.java:4084)
            at android.view.View$PerformClick.run(View.java:16966)
            at android.os.Handler.handleCallback(Handler.java:615)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4745)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
11-16 18:17:53.634    2279-2279/jp.xxxxxxxx.xxxxxxxx.pingtest I/Process﹕ Sending signal. PID: 2279 SIG: 9
まったく解らないので検索してみるとスレッドポリシーを変えてあげれば良さそうでした。
掲示板では以下のコードを追加するような趣旨があり、別にif文で包む格好でなくても create 字にでも同様のコードを実行する形にすれば良さそうですが、SDK_INTの比較が片方では9、もう一方では8になっていたのが気になる部分ではある。
    int SDK_INT = android.os.Build.VERSION.SDK_INT;
    if (SDK_INT > 8) 
    {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                .permitAll().build();
        StrictMode.setThreadPolicy(policy);
        //your codes here

    }
StrictModeはAndroid 2.3でDalvik VMで実装されたようなので APIレベルでいえば9以降となるので比較判定としては SDK_INT > 8 が良さそうです。

原因
Android3.0以降ではメインスレッドでネットワーク操作を行うとエラーとなります。
恒久的な改善策

AsyncTaskやAsyncTaskLoaderを使ってUIスレッドとは別のスレッドで実行する必要があります。

参照
http://stackoverflow.com/questions/25093546/android-os-networkonmainthreadexception-at-android-os-strictmodeandroidblockgua
http://qa.atmarkit.co.jp/q/3312/a/16117/revisions
http://d.hatena.ne.jp/bs-android/20101229/1293582940
http://developer.android.com/about/versions/android-2.3-highlights.html

0 件のコメント:

コメントを投稿