際際滷

際際滷Share a Scribd company logo
GAAD Certification
Md. Moniruzzaman
Sr. Software Engineer
W3 Engineers Ltd.
Date: 16-05-2018
 Mock up the main screens and navigation flow of the application
 Describe interactions between UI, background task, and data
persistence
 Construct a layout using XML or Java code
 Create an Activity that displays a layout resource
 Fetch local data from disk using a Loader on a background
thread
 Propagate data changes through a Loader to the UI
Agenda
After attending this session you are expected to be able to
 Have a clear idea about last slide mentioned topics
Objectives
Typically mid to high fidelity, mockups reflect the design choices for color schemes,
layouts, typography, iconography, the visuals of navigation, and the overall
atmosphere of the product.
In addition to setting aside time to answer the important visual questions, mockups
have several other benefits:
 Intuitive to stakeholders  Thanks to their higher fidelity, mockups require less
context than lo-fi documents like wireframes. Stakeholders can more easily see
the final product.
 Realistic perspective  Its one thing to have all your visual decisions made, but
its another to see them all working together in a way close to the real thing.
Mockups can help reveal problems that arent so apparent on paper (for
example, color clashes, or smaller type crimes going unnoticed).
 Early revisions  Its easier to make revisions in a mockup than in the later
coding stages (as long as the mockup itself isnt coded).
What is a Mockup?
In the design process, mockups come at the end of the lo-fi phase
and the beginning of the hi-fi phase.
keep these tips in mind:
 Narrow your concepts  The reason mockups come after
wireframing is that you first need to eliminate other big picture
options. If youre unclear about the navigation structure, dont
make mockups for both versions  decide one first.
 Examine competitor products  Before deciding your own visuals,
take a look at what your competitors are doing. Dont copy them,
though  look for areas that you can improve upon, or UI patterns
that users would want on all products of this type. A quick heuristic
review can help quantify your observations.
What is a Mockup?
We can divide mockups tools into three different types  graphic design software,
mockup apps, and coded mockups  each with their own advantages and
disadvantages.
 Graphic Design Software: Because of the emphasis on visuals, some designers
prefer to build mockups in the graphic design software theyre most familiar
with. Software like Photoshop is built to create pixel-perfect images.
 Mockup Apps: Tools created specifically for digital product design, like our
app UXPin or Sketch, build upon existing experience with classic tools like
Photoshop.
 Code: Coded mockups are an efficient way to save time and resources provided
youre technically confident. Theres also no surprises later on  if a visual
element cannot be created in code, it is simply fixed right then and there.
3 Types of Mockups
What is it?
Background processing in Android refers to the execution of tasks in
different threads than the Main Thread, also known as UI Thread,
where views are inflated and where the user interacts with our app.
Why background processing?
 To avoid UI blockages by I/O events and prevent the
famous Application Not Responding dialog. A freezing app means
bad UX.
 Some operations are not allowed to run in the Main Thread, such
as HTTP calls.
 To improve performance.
 So, here are some of the best known alternatives,
Interactions between UI, background task
Thread & Handler
 Create a Thread with a Runnable and do the heavy operation, when the heavy
operation ends call the handler created earlier on the UI Thread.
 By default the views have a handler, so you can do View.post(). The Handler is
the means of communication between the heavy task running on the created
thread and the UI Thread.
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
final String result = performBlockingTask();
runOnUiThread(new Runnable() {
@Override
public void run() {
mTextView.setText(result);
}
});
});
thread.start();
Activity.runOnUiThread() simply posts to a main thread Handler internally.
Interactions between UI, background task
Other way,
final Handler handler = new Handler();
final Runnable uiRunnable = new Runnable() {
@Override
public void run() {
mTextView.setText(mResult);
}
};
Thread thread = new Thread(new Runnable() {
public void run() {
mResult = performBlockingTask();
handler.post(uiRunnable);
}
});
thread.start();
Interactions between UI, background task
Overview of Data Storing :
 App data is private to the application
Have several mechanism like:
 State Storage: Ram memory!
 Mechanism for saving Activitys state temporarily
 Preferences
 Lightweight mechanism to store and retrieve key-value pairs
 Files
 Open and save 鍖les on the device or removable storage
 SQLite databases
 Databases
 Content provider is used to give the data to other apps
Data persistence
Activity State: Using RAM:
 Activitys state information can be lost, if its closed
 When activity is no longer on the screen and its
closed because of freeing memory
 When screen rota1on is changed, the activity is destroyed and opened again
 How to store and read state information
 Store state:
 onSaveInstanceState(Bundle)
 Read state
 onRestoreInstanceState(Bundle)
 This will store data only temporarily: for app life1me!
 Data will be held in memory until the app is closed!
Data persistence
Store:
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
String text = tv.getText().toString();
savedInstanceState.putString("someKey", text);
super.onSaveInstanceState(savedInstanceState);
}
Load:
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
String strValue = savedInstanceState.getString("someKey");
if (strValue != null) {
textfield.setText(strValue);
}
}
}
Data persistence
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button myButton = new Button(this);
myButton.setText("Press me");
myButton.setBackgroundColor(Color.YELLOW);
RelativeLayout myLayout = new RelativeLayout(this);
myLayout.setBackgroundColor(Color.BLUE);
EditText myEditText = new EditText(this);
myButton.setId(1);
myEditText.setId(2);
Layout using java code
RelativeLayout.LayoutParams buttonParams =
new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams textParams =
new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
textParams.addRule(RelativeLayout.ABOVE, myButton.getId());
textParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
textParams.setMargins(0, 0, 0, 80);
buttonParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
buttonParams.addRule(RelativeLayout.CENTER_VERTICAL);
myLayout.addView(myButton, buttonParams);
myLayout.addView(myEditText, textParams);
setContentView(myLayout);
}
}
Layout using java code
The ConstraintLayout is a powerful new class, imagine a RelativeLayout on steroids
- yea, thats the ConstraintLayout. It allows us to lay out child views using
constraints to define position based relationships between different views found
in our layout.
The aim of the ConstraintLayout is to help reduce the number of nested views,
which will improve the performance of our layout files.
For example, the attributes of a relative layout allow us to position a view using:
 layout_toRightOf
 layout_toLeftOf
 layout_toTopOf
 layout_toBottomOf
ConstraintLayout
However, the ConstraintLayout features several more attributes:
 layout_constraintTop_toTopOfAlign the top of the desired view to the top of another.
 layout_constraintTop_toBottomOfAlign the top of the desired view to the bottom of another.
 layout_constraintBottom_toTopOfAlign the bottom of the desired view to the top of another.
 layout_constraintBottom_toBottomOfAlign the bottom of the desired view to the bottom of
another.
 layout_constraintLeft_toTopOfAlign the left of the desired view to the top of another.
 layout_constraintLeft_toBottomOfAlign the left of the desired view to the bottom of another.
 layout_constraintLeft_toLeftOfAlign the left of the desired view to the left of another.
 layout_constraintLeft_toRightOfAlign the left of the desired view to the right of another.
 layout_constraintRight_toTopOfAlign the right of the desired view to the top of another.
 layout_constraintRight_toBottomOfAlign the right of the desired view to the bottom of another.
 layout_constraintRight_toLeftOfAlign the right of the desired view to the left of another.
 layout_constraintRight_toRightOfAlign the right of the desired view to the right of another.
If desired, attributes supporting start and end are also available in place of left and right alignment.
ConstraintLayout
By default, device configuration changes such as rotating your screen involve
restarting your whole Activity (one of the many reasons it is so critical not to keep a
reference to your Activity or any Views). The best part about Loaders is
that Loaders survive configuration changes.
But even better: Loaders dont stay around forever. Theyll be automatically
cleaned up when the requesting Activity or Fragment is permanently destroyed.
That means no lingering, unnecessary loads.
Loaders
How to Use Loaders in Android
Class Usage
LoaderManager
Manages your Loaders for you. Responsible
for dealing with the Activity or Fragment
lifecycle
LoaderManager.LoaderCallbacks A callback interface you must implement
Loader The base class for all Loaders
AsyncTaskLoader
An implementation that uses an AsyncTask to
do its work
CursorLoader
A subclass of AsyncTaskLoader for accessing
ContentProvider data
The classes and interfaces of the Loader API :
You do not instantiate the LoaderManager yourself. Instead you simply
call getLoaderManager() from within your activity or your fragment to get hold of it.
Most often you are only interested in two methods of the manager:
 initLoader() and
 restartLoader()
initLoader()
 The initLoader() method adds a Loader to the LoaderManager:
getLoaderManager().initLoader(LIST_ID, null, this);
restartLoader()
* You reset your Loader by using the restartLoader() method. Of course you have to use the
same ID you used for initializing.
getLoaderManager().restartLoader(LIST_ID, null, this);
LoaderManager
The interface LoaderCallbacks defines methods you must implement to create your Loader,
to deal with the results and to clean up resources.
Since the interface is parameterized you must specify the type of data your Loader holds.
Most often the type will be Cursor:
public class YourFragment extends Fragment implements LoaderCallbacks<Cursor> { //... }
The methods you have to implement are:
 onCreateLoader(),
 onLoadFinished() and
 onLoadReset()
LoaderManager.LoaderCallbacks
onCreateLoader():
The LoaderManager calls this method when you call initLoader() for the first time. As
mentioned, the manager only calls this method if no loader for the given ID exists.
A typical example creating a CursorLoader looks like this:
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
CursorLoader loader = new CursorLoader(
this.getActivity(),
SOME_CONTENT_URI,
projection,
selection,
selectionArgs,
sortOrder);
return loader;
}
LoaderManager.LoaderCallbacks
onLoadFinished():
This method is the most interesting one. Here you update the UI based on the
results of your query.
This is how it looks in the sample project:
public void onLoadFinished( Loader<Cursor> loader, Cursor cursor) {
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
int idIndex = cursor.getColumnIndex(LentItems._ID);
int nameIndex = cursor.getColumnIndex(LentItems.NAME);
int borrowerIndex =
cursor.getColumnIndex(LentItems.BORROWER);
this.itemId = cursor.getLong(idIndex);
String name = cursor.getString(nameIndex);
String borrower = cursor.getString(borrowerIndex);
((EditText)findViewById(R.id.name)). setText(name);
((EditText)findViewById(R.id.person)). setText(borrower); } }
LoaderManager.LoaderCallbacks
onLoadReset():
This method allows you to release any resources you hold, so that
the Loader can free them. You can set any references to the cursor
object you hold to null.
But do not close the cursor - the Loader does this for you.
CursorLoader is default Loader if you want your own load then can
create a Custom Loader using AsyncTaskLoader
LoaderManager.LoaderCallbacks
public static class JsonAsyncTaskLoader extends
AsyncTaskLoader<List<String>> {
private List<String> mData;
public JsonAsyncTaskLoader(Context context) {
super(context);
}
@Override
protected void onStartLoading() {
if (mData != null) {
// Use cached data
deliverResult(mData);
}
AsyncTaskLoader
if (mFileObserver == null) {
String path = new File(
getContext().getFilesDir(), "downloaded.json").getPath();
mFileObserver = new FileObserver(path) {
@Override
public void onEvent(int event, String path) {
// Notify the loader to reload the data
onContentChanged();
// If the loader is started, this will kick off
// loadInBackground() immediately. Otherwise,
// the fact that something changed will be cached
// and can be later retrieved via takeContentChanged()
}
};mFileObserver.startWatching();
} if (takeContentChanged() || mData == null) {
// Something has changed or we have no data,
// so kick off loading it
forceLoad();}}
AsyncTaskLoader
@Override
public List<String> loadInBackground() {
// This is on a background thread
// Good to know: the Context returned by getContext()
// is the application context
File jsonFile = new File(
getContext().getFilesDir(), "downloaded.json");
List<String> data = new ArrayList<>();
// Parse the JSON using the library of your choice
// Check isLoadInBackgroundCanceled() to cancel out early
return data;
}
AsyncTaskLoader
@Override
public void deliverResult(List<String> data) {
// Well save the data for later retrieval
mData = data;
// We can do any pre-processing we want here
// Just remember this is on the UI thread so nothing lengthy!
super.deliverResult(data);
}
}
AsyncTaskLoader
You shouldn't use Loaders if you need the background tasks to
complete.
Android destroys Loaders together with the Activities/Fragments
they belong to.
If you want to do some tasks, that have to run until completion, do
not use Loaders. You should use services for this kind of stuff
instead.
Keep in mind that Loaders are special components to help you
create responsive UIs and to asynchronously load data that this UI
component needs
That's the reason why Loaders are tied to the lifecycle of their
creating components. Do not try to abuse them for anything else!
When not to use Loaders
 https://developer.android.com/training/constraint-layout/
 https://medium.com/exploring-android/exploring-the-new-android-
constraintlayout-eed37fe8d8f1
 https://www.techotopia.com/index.php/Creating_an_Android_User_Interface
_in_Java_Code
 https://www.grokkingandroid.com/using-loaders-in-android/
 http://www.androiddesignpatterns.com/2012/08/implementing-loaders.html
 https://medium.com/google-developers/making-loading-data-on-android-
lifecycle-aware-897e12760832
 https://medium.com/elevate-by-lateral-view/background-processing-in-
android-575fd4ecf769
 http://www.theappguruz.com/blog/use-android-cursorloader-example
Resources
Q & A
Thank You

More Related Content

Google Associate Android Developer Certification

  • 1. GAAD Certification Md. Moniruzzaman Sr. Software Engineer W3 Engineers Ltd. Date: 16-05-2018
  • 2. Mock up the main screens and navigation flow of the application Describe interactions between UI, background task, and data persistence Construct a layout using XML or Java code Create an Activity that displays a layout resource Fetch local data from disk using a Loader on a background thread Propagate data changes through a Loader to the UI Agenda
  • 3. After attending this session you are expected to be able to Have a clear idea about last slide mentioned topics Objectives
  • 4. Typically mid to high fidelity, mockups reflect the design choices for color schemes, layouts, typography, iconography, the visuals of navigation, and the overall atmosphere of the product. In addition to setting aside time to answer the important visual questions, mockups have several other benefits: Intuitive to stakeholders Thanks to their higher fidelity, mockups require less context than lo-fi documents like wireframes. Stakeholders can more easily see the final product. Realistic perspective Its one thing to have all your visual decisions made, but its another to see them all working together in a way close to the real thing. Mockups can help reveal problems that arent so apparent on paper (for example, color clashes, or smaller type crimes going unnoticed). Early revisions Its easier to make revisions in a mockup than in the later coding stages (as long as the mockup itself isnt coded). What is a Mockup?
  • 5. In the design process, mockups come at the end of the lo-fi phase and the beginning of the hi-fi phase. keep these tips in mind: Narrow your concepts The reason mockups come after wireframing is that you first need to eliminate other big picture options. If youre unclear about the navigation structure, dont make mockups for both versions decide one first. Examine competitor products Before deciding your own visuals, take a look at what your competitors are doing. Dont copy them, though look for areas that you can improve upon, or UI patterns that users would want on all products of this type. A quick heuristic review can help quantify your observations. What is a Mockup?
  • 6. We can divide mockups tools into three different types graphic design software, mockup apps, and coded mockups each with their own advantages and disadvantages. Graphic Design Software: Because of the emphasis on visuals, some designers prefer to build mockups in the graphic design software theyre most familiar with. Software like Photoshop is built to create pixel-perfect images. Mockup Apps: Tools created specifically for digital product design, like our app UXPin or Sketch, build upon existing experience with classic tools like Photoshop. Code: Coded mockups are an efficient way to save time and resources provided youre technically confident. Theres also no surprises later on if a visual element cannot be created in code, it is simply fixed right then and there. 3 Types of Mockups
  • 7. What is it? Background processing in Android refers to the execution of tasks in different threads than the Main Thread, also known as UI Thread, where views are inflated and where the user interacts with our app. Why background processing? To avoid UI blockages by I/O events and prevent the famous Application Not Responding dialog. A freezing app means bad UX. Some operations are not allowed to run in the Main Thread, such as HTTP calls. To improve performance. So, here are some of the best known alternatives, Interactions between UI, background task
  • 8. Thread & Handler Create a Thread with a Runnable and do the heavy operation, when the heavy operation ends call the handler created earlier on the UI Thread. By default the views have a handler, so you can do View.post(). The Handler is the means of communication between the heavy task running on the created thread and the UI Thread. Thread thread = new Thread(new Runnable() { @Override public void run() { final String result = performBlockingTask(); runOnUiThread(new Runnable() { @Override public void run() { mTextView.setText(result); } }); }); thread.start(); Activity.runOnUiThread() simply posts to a main thread Handler internally. Interactions between UI, background task
  • 9. Other way, final Handler handler = new Handler(); final Runnable uiRunnable = new Runnable() { @Override public void run() { mTextView.setText(mResult); } }; Thread thread = new Thread(new Runnable() { public void run() { mResult = performBlockingTask(); handler.post(uiRunnable); } }); thread.start(); Interactions between UI, background task
  • 10. Overview of Data Storing : App data is private to the application Have several mechanism like: State Storage: Ram memory! Mechanism for saving Activitys state temporarily Preferences Lightweight mechanism to store and retrieve key-value pairs Files Open and save 鍖les on the device or removable storage SQLite databases Databases Content provider is used to give the data to other apps Data persistence
  • 11. Activity State: Using RAM: Activitys state information can be lost, if its closed When activity is no longer on the screen and its closed because of freeing memory When screen rota1on is changed, the activity is destroyed and opened again How to store and read state information Store state: onSaveInstanceState(Bundle) Read state onRestoreInstanceState(Bundle) This will store data only temporarily: for app life1me! Data will be held in memory until the app is closed! Data persistence
  • 12. Store: @Override public void onSaveInstanceState(Bundle savedInstanceState) { String text = tv.getText().toString(); savedInstanceState.putString("someKey", text); super.onSaveInstanceState(savedInstanceState); } Load: @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); if (savedInstanceState != null) { String strValue = savedInstanceState.getString("someKey"); if (strValue != null) { textfield.setText(strValue); } } } Data persistence
  • 13. public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Button myButton = new Button(this); myButton.setText("Press me"); myButton.setBackgroundColor(Color.YELLOW); RelativeLayout myLayout = new RelativeLayout(this); myLayout.setBackgroundColor(Color.BLUE); EditText myEditText = new EditText(this); myButton.setId(1); myEditText.setId(2); Layout using java code
  • 14. RelativeLayout.LayoutParams buttonParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); RelativeLayout.LayoutParams textParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); textParams.addRule(RelativeLayout.ABOVE, myButton.getId()); textParams.addRule(RelativeLayout.CENTER_HORIZONTAL); textParams.setMargins(0, 0, 0, 80); buttonParams.addRule(RelativeLayout.CENTER_HORIZONTAL); buttonParams.addRule(RelativeLayout.CENTER_VERTICAL); myLayout.addView(myButton, buttonParams); myLayout.addView(myEditText, textParams); setContentView(myLayout); } } Layout using java code
  • 15. The ConstraintLayout is a powerful new class, imagine a RelativeLayout on steroids - yea, thats the ConstraintLayout. It allows us to lay out child views using constraints to define position based relationships between different views found in our layout. The aim of the ConstraintLayout is to help reduce the number of nested views, which will improve the performance of our layout files. For example, the attributes of a relative layout allow us to position a view using: layout_toRightOf layout_toLeftOf layout_toTopOf layout_toBottomOf ConstraintLayout
  • 16. However, the ConstraintLayout features several more attributes: layout_constraintTop_toTopOfAlign the top of the desired view to the top of another. layout_constraintTop_toBottomOfAlign the top of the desired view to the bottom of another. layout_constraintBottom_toTopOfAlign the bottom of the desired view to the top of another. layout_constraintBottom_toBottomOfAlign the bottom of the desired view to the bottom of another. layout_constraintLeft_toTopOfAlign the left of the desired view to the top of another. layout_constraintLeft_toBottomOfAlign the left of the desired view to the bottom of another. layout_constraintLeft_toLeftOfAlign the left of the desired view to the left of another. layout_constraintLeft_toRightOfAlign the left of the desired view to the right of another. layout_constraintRight_toTopOfAlign the right of the desired view to the top of another. layout_constraintRight_toBottomOfAlign the right of the desired view to the bottom of another. layout_constraintRight_toLeftOfAlign the right of the desired view to the left of another. layout_constraintRight_toRightOfAlign the right of the desired view to the right of another. If desired, attributes supporting start and end are also available in place of left and right alignment. ConstraintLayout
  • 17. By default, device configuration changes such as rotating your screen involve restarting your whole Activity (one of the many reasons it is so critical not to keep a reference to your Activity or any Views). The best part about Loaders is that Loaders survive configuration changes. But even better: Loaders dont stay around forever. Theyll be automatically cleaned up when the requesting Activity or Fragment is permanently destroyed. That means no lingering, unnecessary loads. Loaders
  • 18. How to Use Loaders in Android Class Usage LoaderManager Manages your Loaders for you. Responsible for dealing with the Activity or Fragment lifecycle LoaderManager.LoaderCallbacks A callback interface you must implement Loader The base class for all Loaders AsyncTaskLoader An implementation that uses an AsyncTask to do its work CursorLoader A subclass of AsyncTaskLoader for accessing ContentProvider data The classes and interfaces of the Loader API :
  • 19. You do not instantiate the LoaderManager yourself. Instead you simply call getLoaderManager() from within your activity or your fragment to get hold of it. Most often you are only interested in two methods of the manager: initLoader() and restartLoader() initLoader() The initLoader() method adds a Loader to the LoaderManager: getLoaderManager().initLoader(LIST_ID, null, this); restartLoader() * You reset your Loader by using the restartLoader() method. Of course you have to use the same ID you used for initializing. getLoaderManager().restartLoader(LIST_ID, null, this); LoaderManager
  • 20. The interface LoaderCallbacks defines methods you must implement to create your Loader, to deal with the results and to clean up resources. Since the interface is parameterized you must specify the type of data your Loader holds. Most often the type will be Cursor: public class YourFragment extends Fragment implements LoaderCallbacks<Cursor> { //... } The methods you have to implement are: onCreateLoader(), onLoadFinished() and onLoadReset() LoaderManager.LoaderCallbacks
  • 21. onCreateLoader(): The LoaderManager calls this method when you call initLoader() for the first time. As mentioned, the manager only calls this method if no loader for the given ID exists. A typical example creating a CursorLoader looks like this: public Loader<Cursor> onCreateLoader(int id, Bundle args) { CursorLoader loader = new CursorLoader( this.getActivity(), SOME_CONTENT_URI, projection, selection, selectionArgs, sortOrder); return loader; } LoaderManager.LoaderCallbacks
  • 22. onLoadFinished(): This method is the most interesting one. Here you update the UI based on the results of your query. This is how it looks in the sample project: public void onLoadFinished( Loader<Cursor> loader, Cursor cursor) { if (cursor != null && cursor.getCount() > 0) { cursor.moveToFirst(); int idIndex = cursor.getColumnIndex(LentItems._ID); int nameIndex = cursor.getColumnIndex(LentItems.NAME); int borrowerIndex = cursor.getColumnIndex(LentItems.BORROWER); this.itemId = cursor.getLong(idIndex); String name = cursor.getString(nameIndex); String borrower = cursor.getString(borrowerIndex); ((EditText)findViewById(R.id.name)). setText(name); ((EditText)findViewById(R.id.person)). setText(borrower); } } LoaderManager.LoaderCallbacks
  • 23. onLoadReset(): This method allows you to release any resources you hold, so that the Loader can free them. You can set any references to the cursor object you hold to null. But do not close the cursor - the Loader does this for you. CursorLoader is default Loader if you want your own load then can create a Custom Loader using AsyncTaskLoader LoaderManager.LoaderCallbacks
  • 24. public static class JsonAsyncTaskLoader extends AsyncTaskLoader<List<String>> { private List<String> mData; public JsonAsyncTaskLoader(Context context) { super(context); } @Override protected void onStartLoading() { if (mData != null) { // Use cached data deliverResult(mData); } AsyncTaskLoader
  • 25. if (mFileObserver == null) { String path = new File( getContext().getFilesDir(), "downloaded.json").getPath(); mFileObserver = new FileObserver(path) { @Override public void onEvent(int event, String path) { // Notify the loader to reload the data onContentChanged(); // If the loader is started, this will kick off // loadInBackground() immediately. Otherwise, // the fact that something changed will be cached // and can be later retrieved via takeContentChanged() } };mFileObserver.startWatching(); } if (takeContentChanged() || mData == null) { // Something has changed or we have no data, // so kick off loading it forceLoad();}} AsyncTaskLoader
  • 26. @Override public List<String> loadInBackground() { // This is on a background thread // Good to know: the Context returned by getContext() // is the application context File jsonFile = new File( getContext().getFilesDir(), "downloaded.json"); List<String> data = new ArrayList<>(); // Parse the JSON using the library of your choice // Check isLoadInBackgroundCanceled() to cancel out early return data; } AsyncTaskLoader
  • 27. @Override public void deliverResult(List<String> data) { // Well save the data for later retrieval mData = data; // We can do any pre-processing we want here // Just remember this is on the UI thread so nothing lengthy! super.deliverResult(data); } } AsyncTaskLoader
  • 28. You shouldn't use Loaders if you need the background tasks to complete. Android destroys Loaders together with the Activities/Fragments they belong to. If you want to do some tasks, that have to run until completion, do not use Loaders. You should use services for this kind of stuff instead. Keep in mind that Loaders are special components to help you create responsive UIs and to asynchronously load data that this UI component needs That's the reason why Loaders are tied to the lifecycle of their creating components. Do not try to abuse them for anything else! When not to use Loaders
  • 29. https://developer.android.com/training/constraint-layout/ https://medium.com/exploring-android/exploring-the-new-android- constraintlayout-eed37fe8d8f1 https://www.techotopia.com/index.php/Creating_an_Android_User_Interface _in_Java_Code https://www.grokkingandroid.com/using-loaders-in-android/ http://www.androiddesignpatterns.com/2012/08/implementing-loaders.html https://medium.com/google-developers/making-loading-data-on-android- lifecycle-aware-897e12760832 https://medium.com/elevate-by-lateral-view/background-processing-in- android-575fd4ecf769 http://www.theappguruz.com/blog/use-android-cursorloader-example Resources
  • 30. Q & A