📜 ⬆️ ⬇️

I / O Schedule 2014: a bad example for learning

We have become accustomed that the application for Google I / O is de facto the standard of application architecture, writing code and design.

So this time, I decided to see what was new in the application. With design everything is clear, more precisely it is clear that people need to learn again how to do it “correctly”. But I was more interested in the code - what is new there?

But I didn’t see anything new, but I realized that the application is absolutely not suitable as a visual aid for training novice developers.
')
After a quick inspection of the code, I got this list of comments.

Disclaimer : I do not pretend to be the ultimate truth; most comments around MySchedule

1. Clearly not enough structure in the UI package.


Why not separate each part into separate packages?
We can consider this remark "far-fetched," but it seems to me that the extra packages here would not have prevented

2. Data loading in MyScheduleActivity.java


We find the updateData method which rakes in data for all days at once, through AsyncTask

Why is this strange and wrong? there are several factors
  1. judging by the fact that they reload the data on onresume they would be approached by a Loader which would do this automatically.
    CursorLoader does not fit, you can use AsyncTaskLoader . Especially since he would load the user if the user left the screen. AsyncTask cannot do this by itself.
  2. in fact, they store the data in the adapter. In this situation, it is more logical to set the data on the model in activation (although I don’t like it either), to create adapters as necessary. and only then feed them a model.

3. Awful MyScheduleAdapter.java


In fact, this is the usual ArrayAdapter , but no, you have to write and inherit everything yourself from the ListAdapter . getView method of sizes in 5 screens! Seriously, google? How to read this canvas?

He was clearly written by several people in the best traditions - “I don’t want to refactor”, “I don’t want to understand”. otherwise, it's a mystery to me why it's worth putting these 3 colors into the members, which are used in getView
mDefaultSessionColor = mContext.getResources().getColor(R.color.default_session_color); mDefaultStartTimeColor = mContext.getResources().getColor(R.color.body_text_2); mDefaultEndTimeColor = mContext.getResources().getColor(R.color.body_text_3); 

and all the others that are used there, no.

4. Strange fragment use - MyScheduleFragment


Go to MyScheduleActivity.java and see how the fragment is used.

 @Override public void onFragmentViewCreated(ListFragment fragment) { fragment.getListView().addHeaderView( getLayoutInflater().inflate(R.layout.reserve_action_bar_space_header_view, null)); int dayIndex = fragment.getArguments().getInt(ARG_CONFERENCE_DAY_INDEX, 0); fragment.setListAdapter(mScheduleAdapters[dayIndex]); fragment.getListView().setRecyclerListener(mScheduleAdapters[dayIndex]); } 


It turns out that the guys needed a ViewPager with a ListView . They didn’t want to play with PagerAdapter and ListView . FragmentPagerAdapter is already there and the fragments are excellent. and the fragment's getListView and setListAdapter methods are public, so why not. (with exactly such arguments the intern came to me when he saw the item “use fragments” in the task).

Error in what? part of the fragment is directly managed from the activit. although the piece should be autonomous.

Solution : if fragmnet cannot independently obtain data (they are formed in one ensemble in activation), then it is necessary to define the interface of the Provider in the fragment, this activation implements the interface and provides the data through it into the fragment. fragmnet will get its data. and put them in the adapter.
But this is almost the same. what they do, the reader will object.
Nearly! It's like eating burgers with borsch, not after. as a result, they get into the stomach, but here's the process.

What is the difference. Fragmet autonomous unit with list and adapter inside. He is able to display data. the problem is only in the data itself - they are not. it is through this interface that we will get them, and not us they will be shoved.

Here is another solution that is better than the first - a fragment can load data for itself! those. loader in the fragment itself. and loads data as much as necessary.

5. The adapters do not use ViewHolder.


all adapters simply pull findViewById.
although we all know how to ViewHolder

6. A bunch of unnecessary observers


each class considers it their duty to hang an observer

comes to obsurd - restart the loader from the observ. although the loader itself should learn everything about changing data.
Itself, if you type the necessary url. again if. SessionsFragment.java

  mSessionsObserver = new ThrottledContentObserver(new ThrottledContentObserver.Callbacks() { @Override public void onThrottledContentObserverFired() { onSessionsContentChanged(); } }); activity.getContentResolver().registerContentObserver( ScheduleContract.Sessions.CONTENT_URI, true, mSessionsObserver); 


7. Improper use of loaders


very often the guys close the cursor in the loader, which is contraindicated - Android Devs

one example
 mTagMetadata = new TagMetadata(cursor); cursor.close(); 

  1. they went completely over the UI
  2. closed the cursor
  3. then they will render tags (they inflate the links and stuff them in LinearLayout)

To release the cursor, you can assign a loader. but if they need it to overload the data on time - then you need to make a custom AsyncTaskLoader + observer (here it will be appropriate).
Loader will load the breaker, bypass it, close it and issue the modelka already.

8. Using inline string instead of constants.


can search by "_uri" code

Maybe I am carping, maybe the code has experienced several generations of developers. but you can still look into the services - there, too, 10-20 akshenov through the switch understand.

IMHO, a novice developer learns about this application is not worth it.

Source: https://habr.com/ru/post/241139/


All Articles