A Service is an application component that can perform long-running operations in the background, and it doesn't provide a user interface.
A Service:
- is decoupled from the user interface
- exists even when there is no user interface
Android architecture components include:
Lifecycle-aware components
LiveData is used to "build data objects that notify views when the underlying database changes".
ViewModel - surviving configuration changes, such as rotation. Managing UI data in a lifecycle-aware way.
Room - SQLite object mapping library. So it converts SQLite table data to Java objects easily. plus, "Room provides compile time checks of SQLite statements and can return RxJava, Flowable and LiveData observables."
Yes. Another middleman!
Content Providers are (seemingly) good abstraction layer between data source and UI. Some advantages of this include data validation.
They enable you to decouple your application layers from the underlying data layers, making your application data-source agnostic by abstracting the underlying data source.
First, we define our schema, which means that we have name of the table(s), columns and their data types organized; on paper.
Then, in the code, we make Contract
class, say BlankContract
and make entry (nested, static) classes in them, say SomeEntry
(which is, well, a table)
import android.provider.BaseColumns; //BaseColumns interface provides _id and _count
public final class BlankContract {
public static final class SomeEntry implements BaseColumns {
So, I dived into SQLite.
Showing tables: .tables
Showing a command which was used to create a table: .schema <table_name>
Showing an actual structure/info about table: PRAGMA TABLE_INFO(<table_name>);
- note that this is a SQL command.
The most human-readable mode of output, I think, is done by this:
Basic outline of Resources/Activity/Fragment connection:
First, we make SettingsActivity. Then, we create SettingsFragment, in which we write addPreferencesFromResource(R.xml.pref_settings);
to connect it with a resource we created in xml
resource directory.
Finally, we make root layout of activity_settings.xml
a fragment, specifically SettingsFragment, with android:name="com.example.android.myapp.SettingsFragment"
Important note: Must not forget adding a style in styles.xml
. Otherwise, app will crash.
If you configured the activity with singleTop launch mode, when you send an intent to android os to get a new instance of such activity, android os will first check the top activity in the back stack, if it is the requested activity type, it will return it, otherwise it will create a new instance of requested activity and return.
Yeah. Just sayin'.
So, let's imagine that we're making Preferences as Settings.
First, we make SettingsActivity
, of course, which is the plain activity we all know of. Its XML must actually be a fragment,
referring to SettingsFragment
(which we'll make; extends PreferenceFragmentCompat
) with android:name
.
Second, we make SettingsFragment with its XML preference xml(<PreferenceScreen and nested preferences in it) in res/xml directory.
And we bond the resource to a Fragment with addPreferencesFromResource
method.
Then, we must not forget to add preference theme(@style/PreferenceThemeOverlay) to styles.xml
, otherwise our app will crash.
onCreate -> Builds UI. Activity is created.
onStart -> Activity is visible.
onResume -> Becomes active foreground app.
In reverse:
Adapter
class is a helper to RecyclerView
. It has three responsibilities: To return how many items should be in RecyclerView, inflate item views from XML and return new ViewHolder instance(object). and populate them with appropriate data(Basically, everything is in this order). So, it has (constructor and) three methods:
Constructor:
public MyAdapter(int numberOfItems, ListItemClickListener onClickListener)
where ListItemClickListener is an interface, which has one void
methoid defined, onListItemClick
.