web-dev-qa-db-ja.com

入力ディスパッチがタイムアウトしたために発生したANR-パブリックIPアドレスを取得しようとしたとき

次の完全なエラーメッセージが表示されます。入力ディスパッチがタイムアウトしました(タッチされたウィンドウは、500.0ms以上前に配信された特定の入力イベントの処理を完了していないため、非キーイベントの送信を待機しています。年齢:9379.7ミリ秒)

以下のコード+トレースを参照してください。次の行であるGetIP_WAN.Java:32でロックが発生するようです。

            BufferedReader br = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));

Wifi-3g/4g-no internetのネットワーク変更を検出するたびに、この関数を呼び出します。他のいくつかの場所で。それはあらゆる場合に発生しますが、ネットワーク変更の検出から明らかになります。

パブリックIPが次のように変更されたかどうかを確認します。

ipwan = giw.getWanIpAddress();

およびgetWanIpAddressで:

ipwan = new GetIP_WAN().execute().get();

ipwanは、パブリックIPを指す文字列です。

このANRを再現することはできません。

私のアプリは、数秒間集中的な非同期タスクになる可能性のあるいくつかの非同期タスクを使用します。強い負荷でテストし、wifiをオフにしても問題はありません。

入力は大歓迎です!!!

public class GetIP_WAN extends AsyncTask<Void, Integer, String> {

    @Override
    protected  String doInBackground(Void... params) {
        URL url;

        String ipwan = null;
        try {
            // get URL content
            url = new URL("http://ipv4bot.whatismyipaddress.com/");
            URLConnection conn = url.openConnection();

            conn.setConnectTimeout(3000);

            // open the stream and put it into BufferedReader
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));

            String inputLine;
            ipwan = br.readLine();

            br.close();
        } catch (Java.net.SocketTimeoutException e) {
            return ("timeout");
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return ("malformed");
        } catch (IOException e) {
            e.printStackTrace();
            return ("exception");
        }
        return (ipwan);
    }

}

そして、ここにトレースがあります(ロックが発生する私のコードは>>>で識別されます):

"main" tid=1 Waiting 
"main" prio=5 tid=1 Waiting
  | group="main" sCount=1 dsCount=0 obj=0x7331b000 self=0xb81bb2c0
  | sysTid=23053 Nice=-4 cgrp=default sched=0/0 handle=0xb6f5cbec
  | state=S schedstat=( 26983505120 16031385654 42843 ) utm=2225 stm=473 core=0 HZ=100
  | stack=0xbe5d4000-0xbe5d6000 stackSize=8MB
  | held mutexes=
  at Java.lang.Object.wait! (Native method)
- waiting on <0x0448108a> (a Java.lang.Object)
  at Java.lang.Thread.parkFor (Thread.Java:1220)
- locked <0x0448108a> (a Java.lang.Object)
  at Sun.misc.Unsafe.park (Unsafe.Java:299)
  at Java.util.concurrent.locks.LockSupport.park (LockSupport.Java:157)
  at Java.util.concurrent.FutureTask.awaitDone (FutureTask.Java:400)
  at Java.util.concurrent.FutureTask.get (FutureTask.Java:162)
  at Android.os.AsyncTask.get (AsyncTask.Java:487)
  >>>   at com.bernard_zelmans.checksecurity.Connectivity.GetInfoWan.getWanIpAddress (GetInfoWan.Java:168)
  >>>   at com.bernard_zelmans.checksecurity.Connectivity.ConnectivityFragment$2.onClick (ConnectivityFragment.Java:155)
  at Android.view.View.performClick (View.Java:4781)
  at Android.view.View$PerformClick.run (View.Java:19874)
  at Android.os.Handler.handleCallback (Handler.Java:739)
  at Android.os.Handler.dispatchMessage (Handler.Java:95)
  at Android.os.Looper.loop (Looper.Java:135)
  at Android.app.ActivityThread.main (ActivityThread.Java:5254)
  at Java.lang.reflect.Method.invoke! (Native method)
  at Java.lang.reflect.Method.invoke (Method.Java:372)
  at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.Java:902)
  at com.Android.internal.os.ZygoteInit.main (ZygoteInit.Java:697)
"AsyncTask #5" tid=21 Native Performing network I/O
"AsyncTask #5" prio=5 tid=21 Native
  | group="main" sCount=1 dsCount=0 obj=0x1372b0a0 self=0xb8537190
  | sysTid=23175 Nice=10 cgrp=bg_non_interactive sched=0/0 handle=0xb8536ee0
  | state=S schedstat=( 9854319 53209536 49 ) utm=0 stm=0 core=0 HZ=100
  | stack=0xa413d000-0xa413f000 stackSize=1036KB
  | held mutexes=
  native: pc 000000000003a180  /system/lib/libc.so (recvfrom+16)
  native: pc 0000000000020165  /system/lib/libjavacore.so (???)
  native: pc 00000000002d557d  /data/dalvik-cache/arm/system@[email protected] (Java_libcore_io_Posix_recvfromBytes__Ljava_io_FileDescriptor_2Ljava_lang_Object_2IIILjava_net_InetSocketAddress_2+176)
  at libcore.io.Posix.recvfromBytes (Native method)
  at libcore.io.Posix.recvfrom (Posix.Java:185)
  at libcore.io.BlockGuardOs.recvfrom (BlockGuardOs.Java:250)
  at libcore.io.IoBridge.recvfrom (IoBridge.Java:553)
  at Java.net.PlainSocketImpl.read (PlainSocketImpl.Java:485)
  at Java.net.PlainSocketImpl.access$000 (PlainSocketImpl.Java:37)
  at Java.net.PlainSocketImpl$PlainSocketInputStream.read (PlainSocketImpl.Java:237)
  at com.Android.okio.Okio$2.read (Okio.Java:113)
  at com.Android.okio.RealBufferedSource.indexOf (RealBufferedSource.Java:147)
  at com.Android.okio.RealBufferedSource.readUtf8LineStrict (RealBufferedSource.Java:94)
  at com.Android.okhttp.internal.http.HttpConnection.readResponse (HttpConnection.Java:179)
  at com.Android.okhttp.internal.http.HttpTransport.readResponseHeaders (HttpTransport.Java:101)
  at com.Android.okhttp.internal.http.HttpEngine.readResponse (HttpEngine.Java:628)
  at com.Android.okhttp.internal.http.HttpURLConnectionImpl.execute (HttpURLConnectionImpl.Java:388)
  at com.Android.okhttp.internal.http.HttpURLConnectionImpl.getResponse (HttpURLConnectionImpl.Java:332)
  at com.Android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream (HttpURLConnectionImpl.Java:199)
  >>>  at com.bernard_zelmans.checksecurity.Connectivity.GetIP_WAN.doInBackground (GetIP_WAN.Java:32)
  >>>  at com.bernard_zelmans.checksecurity.Connectivity.GetIP_WAN.doInBackground (GetIP_WAN.Java:16)
  at Android.os.AsyncTask$2.call (AsyncTask.Java:292)
  at Java.util.concurrent.FutureTask.run (FutureTask.Java:237)
  at Android.os.AsyncTask$SerialExecutor$1.run (AsyncTask.Java:231)
  at Java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.Java:1112)
  at Java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.Java:587)
  at Java.lang.Thread.run (Thread.Java:818)
"WifiManager" tid=22 Native 
"WifiManager" prio=5 tid=22 Native
  | group="main" sCount=1 dsCount=0 obj=0x137192e0 self=0xb85369a0
  | sysTid=23176 Nice=0 cgrp=default sched=0/0 handle=0xb84af978
  | state=S schedstat=( 2818438 6808230 23 ) utm=0 stm=0 core=1 HZ=100
  | stack=0xa4035000-0xa4037000 stackSize=1036KB
  | held mutexes=
  native: pc 000000000003a0ac  /system/lib/libc.so (__epoll_pwait+20)
  native: pc 0000000000011483  /system/lib/libc.so (epoll_pwait+26)
  native: pc 0000000000011491  /system/lib/libc.so (epoll_wait+6)
  native: pc 0000000000010edf  /system/lib/libutils.so (_ZN7Android6Looper9pollInnerEi+98)
  native: pc 0000000000011109  /system/lib/libutils.so (_ZN7Android6Looper8pollOnceEiPiS1_PPv+92)
  native: pc 000000000007e371  /system/lib/libandroid_runtime.so (_ZN7Android18NativeMessageQueue8pollOnceEP7_JNIEnvi+22)
  native: pc 000000000010e76b  /data/dalvik-cache/arm/system@[email protected] (Java_Android_os_MessageQueue_nativePollOnce__JI+102)
  at Android.os.MessageQueue.nativePollOnce (Native method)
  at Android.os.MessageQueue.next (MessageQueue.Java:143)
  at Android.os.Looper.loop (Looper.Java:122)
  at Android.os.HandlerThread.run (HandlerThread.Java:61)
"Heap thread pool worker thread 1" tid=2 Native 
"Heap thread pool worker thread 1" prio=5 tid=2 Native (still starting up)
  | group="" sCount=1 dsCount=0 obj=0x0 self=0xb8337008
  | sysTid=23060 Nice=0 cgrp=default sched=0/0 handle=0xb81c1910
  | state=S schedstat=( 2796719 5468959 19 ) utm=0 stm=0 core=0 HZ=100
  | stack=0xb49ce000-0xb49d0000 stackSize=1020KB
  | held mutexes=
  native: pc 000000000000f9b0  /system/lib/libc.so (syscall+28)
  native: pc 00000000000a8c4b  /system/lib/libart.so (_ZN3art17ConditionVariable4WaitEPNS_6ThreadE+82)
  native: pc 000000000022f877  /system/lib/libart.so (_ZN3art10ThreadPool7GetTaskEPNS_6ThreadE+50)
  native: pc 000000000022f81f  /system/lib/libart.so (_ZN3art16ThreadPoolWorker3RunEv+54)
  native: pc 000000000023005d  /system/lib/libart.so (_ZN3art16ThreadPoolWorker8CallbackEPv+52)
  native: pc 00000000000132bb  /system/lib/libc.so (_ZL15__pthread_startPv+30)
  native: pc 00000000000111e7  /system/lib/libc.so (__start_thread+6)
"Heap thread pool worker thread 2" tid=3 Native 
"Heap thread pool worker thread 2" prio=5 tid=3 Native (still starting up)
  | group="" sCount=1 dsCount=0 obj=0x0 self=0xb81c0ea0
  | sysTid=23061 Nice=0 cgrp=default sched=0/0 handle=0xb833a0b0
  | state=S schedstat=( 5997967 2723698 18 ) utm=0 stm=0 core=0 HZ=100
  | stack=0xb48ce000-0xb48d0000 stackSize=1020KB
  | held mutexes=
  native: pc 000000000000f9b0  /system/lib/libc.so (syscall+28)
  native: pc 00000000000a8c4b  /system/lib/libart.so (_ZN3art17ConditionVariable4WaitEPNS_6ThreadE+82)
  native: pc 000000000022f877  /system/lib/libart.so (_ZN3art10ThreadPool7GetTaskEPNS_6ThreadE+50)
  native: pc 000000000022f81f  /system/lib/libart.so (_ZN3art16ThreadPoolWorker3RunEv+54)
  native: pc 000000000023005d  /system/lib/libart.so (_ZN3art16ThreadPoolWorker8CallbackEPv+52)
  native: pc 00000000000132bb  /system/lib/libc.so (_ZL15__pthread_startPv+30)
  native: pc 00000000000111e7  /system/lib/libc.so (__start_thread+6)
"Heap thread pool worker thread 0" tid=4 Native 
"Heap thread pool worker thread 0" prio=5 tid=4 Native (still starting up)
  | group="" sCount=1 dsCount=0 obj=0x0 self=0xb83390c0
  | sysTid=23059 Nice=0 cgrp=default sched=0/0 handle=0xb82a4b58
  | state=S schedstat=( 3379426 4137085 15 ) utm=0 stm=0 core=1 HZ=100
  | stack=0xb4ace000-0xb4ad0000 stackSize=1020KB
  | held mutexes=
  native: pc 000000000000f9b0  /system/lib/libc.so (syscall+28)
  native: pc 00000000000a8c4b  /system/lib/libart.so (_ZN3art17ConditionVariable4WaitEPNS_6ThreadE+82)
  native: pc 000000000022f877  /system/lib/libart.so (_ZN3art10ThreadPool7GetTaskEPNS_6ThreadE+50)
  native: pc 000000000022f81f  /system/lib/libart.so (_ZN3art16ThreadPoolWorker3RunEv+54)
  native: pc 000000000023005d  /system/lib/libart.so (_ZN3art16ThreadPoolWorker8CallbackEPv+52)
  native: pc 00000000000132bb  /system/lib/libc.so (_ZL15__pthread_startPv+30)
  native: pc 00000000000111e7  /system/lib/libc.so (__start_thread+6)
"HeapTrimmerDaemon" tid=6 Waiting 
"HeapTrimmerDaemon" daemon prio=5 tid=6 Waiting
  | group="system" sCount=1 dsCount=0 obj=0x12c061c0 self=0xb833c230
  | sysTid=23066 Nice=0 cgrp=default sched=0/0 handle=0xb833ca20
  | state=S schedstat=( 16039218 18453438 23 ) utm=1 stm=0 core=3 HZ=100
  | stack=0xa6f4e000-0xa6f50000 stackSize=1036KB
  | held mutexes=
  at Java.lang.Object.wait! (Native method)
- waiting on <0x1c7546fb> (a Java.lang.Daemons$HeapTrimmerDaemon)
  at Java.lang.Daemons$HeapTrimmerDaemon.run (Daemons.Java:311)
- locked <0x1c7546fb> (a Java.lang.Daemons$HeapTrimmerDaemon)
  at Java.lang.Thread.run (Thread.Java:818)
"GCDaemon" tid=7 Waiting 
"FinalizerWatchdogDaemon" tid=8 Waiting 
"Binder_1" tid=9 Native 
"FinalizerDaemon" tid=10 Waiting 
"ReferenceQueueDaemon" tid=11 Waiting 
"Binder_2" tid=12 Native 
"AsyncTask #1" tid=13 Waiting 
"Timer-0" tid=14 Waiting 
"RenderThread" tid=15 Native 
"AsyncTask #2" tid=18 Waiting 
"AsyncTask #3" tid=19 Waiting 
"AsyncTask #4" tid=20 Waiting 
"Binder_3" tid=23 Native 
"AdWorker(Default) #1" tid=24 TimedWaiting 
"Java.lang.ProcessManager" tid=25 Waiting 
"AdWorker(Default) #2" tid=26 TimedWaiting 
"AdWorker(Default) #3" tid=27 TimedWaiting 
"AdWorker(Default) #4" tid=28 TimedWaiting 
"AdWorker(Default) #5" tid=29 TimedWaiting 
"Binder_6" tid=30 Native 
"Binder_4" tid=40 Native 
"Binder_7" tid=45 Native 
"Binder_5" tid=49 Native 
"Signal Catcher" tid=5 Runnable 
"Signal Catcher" daemon prio=5 tid=5 Runnable
  | group="system" sCount=0 dsCount=0 obj=0x12c000a0 self=0xb833abf8
  | sysTid=23062 Nice=0 cgrp=default sched=0/0 handle=0xb8339498
  | state=R schedstat=( 166092660 21972502 124 ) utm=8 stm=8 core=0 HZ=100
  | stack=0xb47c4000-0xb47c6000 stackSize=1012KB
  | held mutexes= "thread list lock" "mutator lock"(exclusive held)
  native: pc 0000000000004758  /system/lib/libbacktrace_libc++.so (_ZN13UnwindCurrent6UnwindEjP8ucontext+23)
  native: pc 0000000000002f8d  /system/lib/libbacktrace_libc++.so (_ZN9Backtrace6UnwindEjP8ucontext+8)
  native: pc 00000000002411c9  /system/lib/libart.so (_ZN3art15DumpNativeStackERNSt3__113basic_ostreamIcNS0_11char_traitsIcEEEEiPKcPNS_6mirror9ArtMethodE+68)
  native: pc 0000000000225591  /system/lib/libart.so (_ZNK3art6Thread4DumpERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE+148)
  native: pc 000000000022e8bb  /system/lib/libart.so (_ZN3art10ThreadList14DumpForSigQuitERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE+142)
  native: pc 0000000000215ca5  /system/lib/libart.so (_ZN3art7Runtime14DumpForSigQuitERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE+68)
  native: pc 000000000021a431  /system/lib/libart.so (_ZN3art13SignalCatcher13HandleSigQuitEv+752)
  native: pc 000000000021aadb  /system/lib/libart.so (_ZN3art13SignalCatcher3RunEPv+318)
  native: pc 00000000000132bb  /system/lib/libc.so (_ZL15__pthread_startPv+30)
  native: pc 00000000000111e7  /system/lib/libc.so (__start_thread+6)
9
narb

あなたの問題は、GetIP_WAN()。execute()を呼び出した直後にAsyncTask.get()を呼び出していることだと思います。 UIスレッドでGetIP_WAN()。execute()を呼び出していると思います。 onClickコールバックまたはBroadcastReceiverにある場合、最も確実です。したがって、GetIP_WANタスクはバックグラウンドスレッドで正しく実行されていますが、get()呼び出しはdoInBackground()から返されるデータを取得しようとしています。しかし、その呼び出し(get())は[〜#〜] never [〜#〜] doInBackgroundの前に戻り、おそらくonPostExecute(...)が戻るため、UIスレッドでブロッキングが発生します。 AsyncTaskクラスの内部に入るためのドキュメントを読むと、

/** * Waits if necessary for the computation to complete, and then * retrieves its result. * * @return The computed result. * * @throws CancellationException If the computation was cancelled. * @throws ExecutionException If the computation threw an exception. * @throws InterruptedException If the current thread was interrupted * while waiting. */

皮肉なことに、あなたはAsnycTaskの目的を否定しています。バックグラウンドスレッドで作業が行われている場合でも、UIスレッドでの追加処理が完了する前に、UIスレッドに作業の完了を強制的に待機させます。 Android OSは、UI /メインスレッドが5秒間ブロックされていることを検出すると、ANRダイアログの作成を処理します。

Getを呼び出しているので、GetIP_WANからデータを取得できるので、UIスレッドで操作/表示できます。私が推奨するのは、所有するアクティビティまたはフラグメントへの参照の何らかの形式をGetIP_WANに渡し、タスクが完了してUI /メインスレッドで起動されるonPostExecute(...)を起動すると、アクティビティまたはフラグメントに基づいてアクションを実行することですdoInBackground(...)でダウンロードしたデータでUIを更新します。私がお勧めするパターンの1つは、WeakReference内でラップされたHandler参照をGetIP_WANに渡し、onPostExecute(...)で、作業が完了したことを示す空のメッセージを送信し、GetIP_WAN.get()を呼び出しても安全であることです。

8
Wade Wilson