android.text.method.LinkMovementMethod

Jan 10, 2015 20:54

А вот такая тема. Допустим, колбасим под android и захотелось нам, что б в нашем TextView ссылки были нажимабельными. Нормальное такое желание. Что б, если клик по телефону - запускалась звонилка, а если по e-mail - открывался почтовый клиент. Сказано - сделано! Гуглим и первой же ссылкой находим какой-нибудь вопрос-ответ на StackOverflow, говорящий нам сделать что-то подобное:

TextView someTextView = ...

someTextView.setMovementMethod(LinkMovementMethod.getInstance());Запиливаем, и о-ба-на! Работает! Даём потестить тестерам - работает! Огонь! Релизим. А после релиза начинаем ловить падения :)

А дело вот в чём. Понятно, что открытия всех этих звонилок, e-mail клиентов и прочих браузеров происходят через запуск активности, который на android можно сделать многими способами. LinkMovementMethod делает это (по крайне мере на момент версии робота 5.0) через вызов onClick у ClickableSpan, который в свою очередь, будучи на самом деле URLSpan'ом, зовёт банальный Context.startActivity, документация на который говорит, что если активность под Intent не будет найдена, то будет выброшено исключение ActivityNotFoundException! А что у нас есть? Правильно, «рутованые» телефоны без e-mail клиентов, китайские планшеты без звонилок и прочие весёлые устройства.

Лечится дело не очень красиво, зато наверняка: наследуемся от LinkMovementMethod и заворачиваем все его методы в try {} catch (Throwable e) {}.

Можно, конечно, попробовать замутить свой URLSpan, но это отдельная тема, про которую сейчас лениво писать.

А интересность тут в том, что этот самое злосчастное исключение бросается в стеке вызовов к которому наш код, обычно, мало отношения имеет. То есть use case вообще не рассчитан на обработку пользовательским кодом и вообще никакой не use case, а банальный ляп товарищей из гугла. Естественно, цветёт и пахнет по сей день в свежайшей версии android.

искалеченный android, android

Previous post Next post
Up