Android – Отправка ключей по тайм-ауту

В моем приложении для Android я получаю очень странный сбой, когда я нажимаю кнопку (изображение) на своем пользовательском интерфейсе, все приложение зависает, и через пару секунд я получаю диалоговое окно с ужасной силой.

Вот что печатается в журнале:


WARN/WindowManager(88): Key dispatching timed out sending to package name/Activity WARN/WindowManager(88): Dispatch state: {{KeyEvent{action=1 code=5 repeat=0 meta=0 scancode=231 mFlags=8} to Window{432bafa0 com.android.launcher/com.android.launcher.Launcher paused=false} @ 1281611789339 lw=Window{432bafa0 com.android.launcher/com.android.launcher.Launcher paused=false} [email protected] fin=false gfw=true ed=true tts=0 wf=false fp=false mcf=Window{4335fc58 package name/Activity paused=false}}} WARN/WindowManager(88): Current state: {{null to Window{4335fc58 package name/Activity paused=false} @ 1281611821193 lw=Window{4335fc58 package name/Activity paused=false} [email protected] fin=false gfw=true ed=true tts=0 wf=false fp=false mcf=Window{4335fc58 package name/Activity paused=false}}} INFO/ActivityManager(88): ANR in process: package name (last in package name) INFO/ActivityManager(88): Annotation: keyDispatchingTimedOut INFO/ActivityManager(88): CPU usage: INFO/ActivityManager(88): Load: 5.18 / 5.1 / 4.75 INFO/ActivityManager(88): CPU usage from 7373ms to 1195ms ago: INFO/ActivityManager(88): package name: 6% = 1% user + 5% kernel / faults: 7 minor INFO/ActivityManager(88): system_server: 5% = 4% user + 1% kernel / faults: 27 minor INFO/ActivityManager(88): tiwlan_wifi_wq: 3% = 0% user + 3% kernel INFO/ActivityManager(88): mediaserver: 0% = 0% user + 0% kernel INFO/ActivityManager(88): logcat: 0% = 0% user + 0% kernel INFO/ActivityManager(88): TOTAL: 12% = 5% user + 6% kernel + 0% softirq INFO/ActivityManager(88): Removing old ANR trace file from /data/anr/traces.txt INFO/Process(88): Sending signal. PID: 1812 SIG: 3 INFO/dalvikvm(1812): threadid=7: reacting to signal 3 INFO/dalvikvm(1812): Wrote stack trace to '/data/anr/traces.txt' 

Это код кнопки (изображение):


 findViewById(R.id.endcallimage).setOnClickListener(new OnClickListener() { public void onClick(View v) { mNotificationManager.cancel(2); Log.d("Handler", "Endcallimage pressed"); if(callConnected) elapsedTimeBeforePause = SystemClock.elapsedRealtime() - stopWatch.getBase(); try { serviceBinder.endCall(lineId); } catch (RemoteException e) { e.printStackTrace(); } dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.FLAG_SOFT_KEYBOARD)); dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK)); } }); 

Если я прокомментирую следующее: нажатие кнопки (изображения) не вызывает аварии:


 try { serviceBinder.endCall(lineId); } catch (RemoteException e) { e.printStackTrace(); } 

Вышеприведенный код вызывает несколько уровней приложения и на нативный уровень (NDK), может ли вызов, проходящий через несколько объектов, привести к силе закрытия? Кажется маловероятным, поскольку несколько других кнопок делают то же самое без проблем.

Как насчет нативного слоя? Может ли какой-то код, который я создал с NDK, вызвать проблему?

Какие-либо другие идеи относительно того, что может быть причиной проблемы?

Вы должны быть как можно быстрее в своей реализации onClick. Дорогостоящие операции должны быть, в общем, выгружены в фоновый stream.

В onClick попробуйте:

 Thread t = new Thread(){ public void run(){ your_stuff(); } }; t.start(); 

а не просто

 your_stuff() 

Вы можете столкнуться с этой ошибкой, когда вы блокируете основной stream (иначе stream пользовательского интерфейса) в течение нескольких секунд. Дорогостоящие операции должны быть, в общем, выгружены в фоновый stream. AsyncTask очень полезен в этих случаях.

В вашем случае вы можете сделать следующее:

 new AsyncTask() { @Override protected Void doInBackground(Void... params) { try { serviceBinder.endCall(lineId); } catch (RemoteException e) { e.printStackTrace(); } } }.execute(); 

Сделайте свою длинную операцию в отдельной нити или используйте AsyncTask, чтобы избавиться от ANR.

ANR (Activity Not Responding) происходит, когда long operation takes place in the "main" нити происходит некоторая long operation takes place in the "main" . Это stream цикла событий, и если он занят, Android не может обрабатывать какие-либо дополнительные события GUI в приложении и, таким образом, вызывает ANR dialog .

Ваша деятельность заставила долго говорить об ОС Android «эй, я все еще жив»! (Это то, что делает stream пользовательского интерфейса).

http://developer.android.com/guide/practices/design/responsiveness.html

В принципе, если вы делаете stream пользовательского интерфейса выполняете сложную задачу, он слишком занят, делая свою задачу, чтобы сообщить ОС, что она все еще «жива».

http://android-developers.blogspot.co.uk/2009/05/painless-threading.html

Вы должны переместить код анализа XML в другой stream, а затем использовать обратный вызов, чтобы сообщить, что stream пользовательского интерфейса вы закончили, и что-то сделать с результатом.

http://developer.android.com/resources/articles/timed-ui-updates.html

Обнаружение того, где происходят ANR, легко, если это постоянный блок (например, тупик, который вызывает некоторые блокировки), но сложнее, если это всего лишь временная задержка. Во-первых, перейдите по своему коду и посмотрите на загружаемые места и длительные операции. Примеры могут включать использование сокетов, блокировок, спальных streamов и других операций блокировки из streamа событий. Вы должны убедиться, что все это происходит в отдельных streamах. Если ничего не возникает, используйте DDMS и включите просмотр streamа. Это показывает все streamи в вашем приложении, похожие на трассировку. Воспроизводите ANR и одновременно обновите основной stream. Это должно показать вам, что именно происходит во время ANR

Если Logcat не выводит ничего полезного, попробуйте вытащить traces.txt из /data/anr/traces.txt

 adb pull /data/anr/traces.txt . 

поскольку он может дать больше информации о том, где произошло исключение ANR

И эта ссылка может также помочь при создании AsyncTask и Threads

Если вы выполняете ресурсоемкую задачу, это может произойти. Возобновление деятельности. 1. Попробуйте остановить всю свою интенсивную работу onPause, а затем перезапустить его onResume. 2. Если вы показываете карту на наложении Activity activity, то прекратите обновление оверлеев во время сна. А затем перезапустите его onResume.

Interesting Posts

Что конкретно представляет собой цикл событий Node.js?

Ошибка при загрузке виртуальной машины Windows 95 в Windows Virtual PC

Удаление нескольких программ в Windows 7?

Каков ваш метод маркировки «folksonomy» для файлов на вашей локальной машине?

вырезать часть растрового изображения

Предоставить доступ к моей локальной компьютерной форме вне

Ограничение типа множественного типа (ИЛИ)

Избегайте синхронизации (это) в Java?

Endless RecyclerView с ProgressBar для разбивки на страницы

Переименуйте несколько файлов, заменив определенный шаблон в именах файлов, используя сценарий оболочки

Каков стандарт де-факто для обратного прокси-сервера, чтобы указать бэкэнд-SSL?

Как установить фильтры Visual Studio для вложенной подкаталога с помощью cmake

Как определить текущий размер ARC в ZFS и как ARC относится к свободной или кэш-памяти?

Способы дедупликации файлов

Могу ли я изменить анимацию перехода startActivity () Android?

Давайте будем гением компьютера.