Существует ли инструмент Android, чтобы найти название макета для работающего приложения?
Фон
Меня недавно наняли для работы с очень большой программой (только два вида деятельности, около ста фрагментов и несколько сотен макетов). Кроме того, большая часть содержимого макетов (изображений и текста), а также порядок их отображения динамически определяются через веб-API компании.
К сожалению, нет документации. Нет карты, нада. Компания наняла стороннего производителя для создания этого приложения задолго до того, как у них появились программисты на Android. И качество кода в лучшем случае плохое (даже имена переменных сбивают с толку и противоречивы).
Следовательно, я трачу около 70% - 90% своего времени на простой поиск макетов и кода, просто чтобы изменить фон кнопки.
Вопрос
Есть ли инструмент, который можно запустить (возможно, в отладчике Android Studio?), Который может каким-то образом выплевывать имена файлов макета, которые отображаются в данный момент?
Мои начальники часто говорят что-то вроде: "Измените текстуру фона с черного на светло-серый". И я думаю: изменение тривиально, но поиск XML-файла может занять час.
--Обновить--
Проект, который породил этот вопрос, больше не находится под моим контролем, поэтому этот вопрос стал спорным. Но, похоже, это общая проблема, поэтому я оставляю этот вопрос открытым. Возможно, в будущем появится какой-нибудь инструмент / решение. Я надеюсь, что эта тема будет полезна для других программистов в этой ситуации.
7 ответов
Существует также приложение Developer Assistant для Android, которое может проверять иерархию представлений во время выполнения и затем отображать наиболее вероятные имена макетов, видимые на экране. Эвристика включена, поэтому она не будет работать на 100% с точностью, но все же может быть полезна и работает полностью в автономном режиме (раскрытие: я сделал это приложение).
Пример:
Инструмент просмотра иерархии
В Android Device Monitor есть кнопка, которую вы можете нажать, которая называется "Иерархия просмотра дампа для UI Automator".
Это откроет просмотрщик иерархии пользовательского интерфейса в мониторе устройств, который можно использовать для просмотра идентификаторов ресурсов каждого из ваших представлений.
Хотя на самом деле это не дает вам имя завышенного XML-файла, это может быть очень полезно. Если вам повезет, вы можете даже использовать идентификаторы ресурсов, чтобы сузить поиск файлов XML для поиска.
И если вы наведете указатель мыши на заголовок окна программы просмотра, он покажет вам путь к фактическому XML-файлу, который он создал. Это способ найти все идентификаторы ресурсов в одном месте.
Еще немного информации о Hierarchy Viewer на случай, если это поможет:
- Как добраться до Hierarchy View при запуске приложения на моем устройстве, подключенном к Android Studio
- или прямо из документации разработчика Android
Средство просмотра иерархии позволяет отлаживать и оптимизировать пользовательский интерфейс. Он обеспечивает визуальное представление иерархии представления макета (представление макета) и увеличенный инспектор дисплея (представление Pixel Perfect).
Создать пользовательский макет Inflater в коде
Вот запись в блоге, которая содержит что-то интересное - пользовательский макет, который перехватывает всю инфляцию представления:
Может быть возможно использовать этот пример кода для перехвата раздуваемых вызовов и получения идентификатора ресурса файла XML:
LayoutInflator.inflate()
на Android документы разработчика
На этом этапе вам нужно будет превратить идентификатор ресурса в полезное имя. Цитируя этот вопрос ( Как получить имя ресурса из идентификатора ресурса), вы можете использовать:
getResources().getResourceEntryName(int resid);
Добавьте некоторую регистрацию, и это может дать вам каждый файл XML по мере его надувания.
Это может быть хорошим способом документировать весь ваш проект.
Возможно "Android/sdk/tools/uiautomatorviewer" может вам помочь. Он может получить дамп текущего экрана с устройства и показать вам виды / макеты с их деталями - также с идентификаторами
Вы можете попробовать этот инструмент: https://github.com/nekocode/ResourceInspector
Он может проверять все используемые файлы макетов текущей деятельности.
Начиная с версии Android 3.0 и выше, инструмент просмотра иерархии устарел. Есть автономный LayoutInspector
, Вы можете получить к нему доступ, нажав на инструменты в верхней панели Android Studio.
Вдохновленный @nekocode ResourceInspector, я выяснил, как показать имя ресурса макета на скриншоте, снятом инспектором макетов AS.
Сначала создайте класс LayoutIndicatorInflater
public class LayoutIndicatorInflater extends LayoutInflater {
private LayoutInflater mOriginalInflater;
private String mAppPackageName;
protected LayoutIndicatorInflater(LayoutInflater original, Context newContext) {
super(original, newContext);
mOriginalInflater = original;
mAppPackageName = getContext().getPackageName();
}
@Override
public LayoutInflater cloneInContext(Context newContext) {
return new LayoutIndicatorInflater(mOriginalInflater.cloneInContext(newContext), newContext);
}
@Override
public void setFactory(Factory factory) {
super.setFactory(factory);
mOriginalInflater.setFactory(factory);
}
@Override
public void setFactory2(Factory2 factory) {
super.setFactory2(factory);
mOriginalInflater.setFactory2(factory);
}
@Override
public View inflate(int resourceId, ViewGroup root, boolean attachToRoot) {
Resources res = getContext().getResources();
String packageName = "";
try {
packageName = res.getResourcePackageName(resourceId);
} catch (Exception e) {}
String resName = "";
try {
resName = res.getResourceEntryName(resourceId);
} catch (Exception e) {}
View view = mOriginalInflater.inflate(resourceId, root, attachToRoot);
if (!mAppPackageName.equals(packageName)) {
return view;
}
View targetView = view;
if (root != null && attachToRoot) {
targetView = root.getChildAt(root.getChildCount() - 1);
}
targetView.setContentDescription("layout res:" + resName);
if (targetView instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) targetView;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View child = viewGroup.getChildAt(i);
if (TextUtils.isEmpty(child.getContentDescription())) {
child.setContentDescription("layout res:" + resName);
}
}
}
return view;
}
}
Затем создайте вспомогательный класс
public class LayoutIndicatorHelper {
public static void init(Application application) {
if (BuildConfig.DEBUG) {
application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
try {
Field inflaterField = ContextThemeWrapper.class.getDeclaredField("mInflater");
inflaterField.setAccessible(true);
LayoutInflater inflater = (LayoutInflater) inflaterField.get(activity);
LayoutInflater proxyInflater = null;
if (inflater != null) {
proxyInflater = new LayoutIndicatorInflater(inflater, activity);
inflaterField.set(activity, proxyInflater);
}
Class phoneWindowClass = Class.forName("com.android.internal.policy.PhoneWindow");
Field phoneWindowInflater = phoneWindowClass.getDeclaredField("mLayoutInflater");
phoneWindowInflater.setAccessible(true);
inflater = (LayoutInflater) phoneWindowInflater.get(activity.getWindow());
if (inflater != null && proxyInflater != null) {
phoneWindowInflater.set(activity.getWindow(), proxyInflater);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
}
}
}
Наконец позвони LayoutIndicatorHelper.init
в вашем Application
"s onCreate
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
LayoutIndicatorHelper.init(this);
}
}
Возможно, это слишком поздно, но мой ответ могут использовать разные программисты.
Библиотека Stetho в Facebook - это замечательный инструмент для проверки работоспособности приложений. Библиотека Stetho работает как расширение Chrome и будет похожа для многих программистов.
Кроме того, увидеть HTTP-запрос / ответы очень легко с помощью Stetho. Я абсолютно советую каждому программисту Android попробовать.