Моя карьера началась как разработчик iOS, а недавно я начал руководить командами iOS и Android. Спустя несколько недель я не мог не заметить сходства между двумя платформами на уровне инфраструктуры.
Я считаю, что обе команды разработчиков, iOS и Android, должны разделять архитектурные решения и терминологию. В конце концов, оба приложения имеют одинаковую логику, возможности и пользовательский интерфейс.
Я собираюсь ориентироваться в основном на проекты iOS, в которых не используются раскадровки, я их не фанат. Начнем сначала с краткого обзора:
AppDelegate против MainActivity
Последние рекомендации по разработке Android продвигают использование одного класса активности и нескольких фрагментов (да, я знаю, что не все приложения построены таким образом, но, похоже, это последняя передовая практика для большинства случаев).
AppDelegate и MainActivity очень похожи, они оба являются «точкой входа» приложений и местом, где вы обычно должны размещать свои первые экземпляры приложения, или, если вы используете инъекцию зависимостей (и вы должны), это то место, где вы обычно запускаете его. .
iOS: AppDelegate class AppDelegate: UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { //Entry point (In case you do not use storyboards) } } Android: MainActivity public abstract class MainActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { //Entry point } }
UIViewController против фрагмента
Оба класса действуют как представитель пользовательского интерфейса экрана (или его часть), получают события жизненного цикла приложения и реакцию на взаимодействие с пользователем.
Примечание. Я считаю само собой разумеющимся, что вы используете шаблон проектирования MVVM, поэтому оба класса содержат только элементы пользовательского интерфейса и связаны с некоторой ViewModel для обновления при изменении состояния приложения.
Назначение событий жизненного цикла очень похоже, но в UIViewController их гораздо больше. Например, ViewWillAppear будет срабатывать всякий раз, когда представление будет представлено на экране, ViewDidAppear сработает, когда представление будет представлено. Фрагменты не обладают этой способностью, вместо этого вам придется обойти это истинными способами.
Android: Fragment class MyFragment: DialogFragment { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? { //First allocations/inflate //View setup will happen on "onViewCreated" } } iOS: UIViewController class ViewController: UIViewController{ override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) //First allocations //Some programmers would use "ViewDidLoad" for this purpose } }
UITableView против RecycleView
В первые дни iOS была известна своей высокой производительностью по сравнению с Android.
Это во многом связано с повторным использованием представлений для более быстрой прокрутки (60 кадров в секунду).
iOS использует UITableView с момента своего первого запуск. Чтобы быть более конкретным, iOS 2 (которая была первой iOS, которая поддерживала стороннее приложение через AppStore).
UITableView повторно использует свои ячейки (специфичное для платформы имя для элементов строк), потому что создание новых единицы, по одному для каждой прокрутки.
В CellForRawAtIndexPath вы получите новый или переработанный экземпляр текущей ячейки для каждого индекса и сможете настроить его представление.
Android, с другой стороны, сначала начал с компонента под названием «ListView», который страдал от отсутствия механизма повторного использования и низкой производительности.
«RecycleView» пришел на помощь на Google I / O 2014. Его название подразумевает, что он перерабатывает представления.
RecycleView использует адаптер (модель – представление – адаптер), который определяет, сколько элементов будет отображаться, какие типы элементов , раздувание (создание представлений из XML) и установка / привязка элементов с новыми представленными данными прокрутки.
RecycleView использует ViewHolder для хранения ссылки на созданные элементы, вместо того, чтобы создавать новые экземпляры (раздувая их), он повторно использует уже существующие.
iOS: UITableView class MyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { let tableView = UITableView.init() override func viewDidLoad() { super.viewDidLoad() self.tableView.delegate = self self.tableView.dataSource = self } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { //You will get passed a recycle cell, or a new one. } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ //Number of rows displayed } } Android: RecycleView class MyFragment : DialogFragment { var adapter: MyAdaptor override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) homeRecycler.layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false) homeRecycler.adapter = this.adapter } } class MyAdaptor : RecyclerView.Adapter<RecyclerView.ViewHolder>() { var items: List<HomeFeedItem> = listOf() override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { // Bind ViewHolder to current item props if (holder is MyViewHolder) { holder.bindViews(items[position]) return } } override fun getItemViewType(position: Int): Int { return items[position].itemType().intValue() } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { // This is the magic. Inflating will happen only once to improve performance val inflate: CardView = LayoutInflater.from(context).inflate(R.layout.myLayout, parent, false) as CardView return MyViewHolder(inflate) } fun setFeed(items: List<HomeFeedItem>) { //Reload list modals this.items = items this.notifyDataSetChanged() } override fun getItemCount() = items.size }
Макет: ограничения XML VS
Сначала я скажу следующее: я был удивлен компоновкой Android, потому что она хорошо работает. Легко начать (особенно если у вас есть опыт веб-разработки).
Конструктор интерфейсов Android тоже отлично работает, отражая точное состояние XML, экономя много времени на компиляции.
iOS использует макет ограничения, так называемый «выраженный» способ определения макета с помощью кода (или раскадровки). У него большая кривая обучения, поскольку он не работает, как любой другой фреймворк (по крайней мере, который я использовал в прошлом), и имеет несколько важных тем, таких как приоритеты, поддержка контента, сопротивление сжатию и многое другое, которые довольно сложно понять. сначала обойдите вокруг.
По сути, ограничения - это объекты, которые определяют отношения между объектами пользовательского интерфейса и могут быть добавлены с помощью кода или Interface Builder.
Android, с другой стороны, использует XML-макет, очень похожий на некоторые популярные веб-фреймворки, и прекрасно работает с вашей IDE. Хотите цвет отступов / полей / фона? Не уверены в синтаксисе? Просто начните вводить текст, и Android Studio выполнит автозаполнение именно тем, что вы хотели.
В следующем сообщении в блоге я собираюсь затронуть следующие темы:
Dagger vs Swinject
Навигация по приложениям
Реализация MVVM
Подробнее откуда это взялось
Эта история публикуется в журнале Noteworthy, куда каждый день приходят тысячи людей, чтобы узнать о людях и идеях, формирующих наши любимые продукты.
Следите за нашей публикацией, чтобы увидеть больше историй о продуктах и дизайне, представленных командой Журнала.