GoConqr hat ein neues Design! Sag uns, wie es dir gefällt.

Notizen

Android Application Architecture

vishal bhalerao Coding Englisch 5 Seiten

Inhalt der Notizen (5)

Seite 1

The most important thing you should focus on is the separation of concerns in your app.

Any code that does not handle a UI or operating system interaction should not be in activity and fragment

you should drive your UI from a model, preferably a persistent model. Persistence is ideal for two reasons:

your users won't lose data if OS destroys your app to free up resources

and your app will continue to work even when a network connection is flaky or not connected.

4.Models are independent from the Views and app components in your app, hence they are isolated from the life cycle issues of those components

#.Recommended app architecture

Imagine we're building a UI that shows a user profile. This user profile will be fetched from our own private back end using a REST API.

1.Building the user interface

1.extend your ViewModel by ViewModel class.

It holds ;-

UserID - userID passed to fragments through arguments.

UserDetails(POJO) - holds user details.

ViewModel WHY -

For simple data, the activity can use the onSaveInstanceState() method and restore its data from the bundle in onCreate(), but this approach is only suitable for small amounts of data like UI state, not for potentially large amounts of data like a list of users.

these UI controllers (activities, fragments, and so on) frequently need to make some asynchronous calls which may take some time to return. The UI controller needs to manage these calls and clean them up when it is destroyed to avoid potential memory leaks. This requires a lot of maintenance, and in the case where the object is re-created for a configuration change, it is a waste of resources since it needs to re-issue the same call.

Last but not least, these UI controllers already need to react to user actions or handle the operating system communication. When they also need to handle their resources manually, it bloats the class, creating "god activities" (or "god fragments"); that is, a single class that tries to handle all of an app's work by itself, instead of delegating work to other classes. This also makes testing a lot harder.

Android Application Architecture

It is easier and more efficient to separate out view data ownership from UI controller logic. Lifecycles provides a new class called ViewModel, a helper class(middle block) for the UI controller which is responsible for preparing the data for the UI. The ViewModel is automatically retained during configuration changes so that the data it holds is immediately available to the next activity or fragment instance.

CODE:-

1.viewModel:-

public class UserProfileViewModel extends ViewModel {

private String userId;

private User user;

public void init(String userId) {

this.userId = userId;

}

public User getUser() {

return user;

}

}

2.Fragment:-

public class UserProfileFragment extends LifecycleFragment {

private static final String UID_KEY = "uid";

private UserProfileViewModel viewModel;

@Override

public void onActivityCreated(@Nullable Bundle savedInstanceState) {

super.onActivityCreated(savedInstanceState);

String userId = getArguments().getString(UID_KEY);

viewModel = ViewModelProviders.of(this).get(UserProfileViewModel.class);

viewModel.init(userId);

}

@Override

public View onCreateView(LayoutInflater inflater,

@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

return inflater.inflate(R.layout.user_profile, container, false);

}

}

Search LifecycleOwner. -A class that has an Android lifecycle. These events can be used by custom components to handle lifecycle changes without implementing any code inside the Activity or the Fragment.

LiveData:-

WTF is that ? how it came om nowhere ?

- how do we connect Viewmodel and UI handler? After all, when the ViewModel's user field is set, we need a way to inform the UI. This is where the LiveData class comes in.

LiveData is an observable data holder. It lets the components in your app observe LiveData objects for changes without creating explicit and rigid dependency paths between them

LiveData also respects the lifecycle state of your app components (activities, fragments, services) and does the right thing to prevent object leaking so that your app does not consume more memory.

The great thing about LiveData is that it is lifecycle aware and will automatically clean up references when they are no longer needed.

any alternative to LiveData ?

- YES

1. RxJava

2. Agera

But - you need to handle life cycle problems of activity and fragments

observe in activity:

Code:-

replace the User field in the User with a LiveData<User> so that the fragment can be informed when the data is updated

ViewMOdel;-

public class UserProfileViewModel extends ViewModel {

...

// private User user;

private LiveData<User> user;

public LiveData<User> getUser() {

return user;

}

}

rag/Activity:-

@Override

public void onActivityCreated(@Nullable Bundle savedInstanceState) {

super.onActivityCreated(savedInstanceState);

viewModel.getUser().observe(this, user -> {

// update UI

});

}

HOW it works ??

Every time the user data is updated, the onChanged callback will be invoked and the UI will be refreshed.

we didn't have to override the fragment's onStop() method to stop observing the data. This is not necessary with LiveData because it is lifecycle aware, which means it will not invoke the callback unless the fragment is in an active state (received onStart() but did not receive onStop()).

LiveData will also automatically remove the observer when the fragment receives onDestroy().

​​​​​​​And the best part

We also didn't do anything special to handle configuration changes (for example, user rotating the screen). The ViewModel is automatically restored when the configuration changes, so as soon as the new fragment comes to life, it will receive the same instance of ViewModel (this is what they call getting codegasam)and the callback will be called instantly with the current data. This is the reason why ViewModels should not reference Views directly; they can outlive the View's lifecycle. SeeThe lifecycle of a ViewModel.

Seite 2

2.Fetching Data :

how does the ViewModel fetch the user data?

-assume that our backend provides a REST API. We will use the Retrofit library to access our backend.

BUT Where i should call Retrofit?

in ViewModel ? or Activity ?

Not viewmodel :-

scope of a ViewModel is tied to an Activity or Fragment lifecycle, so losing all of the data when its lifecycle is finished is a bad user experience.

SO ViewModel will delegate this work to a new Repository module.

WE got the new Module banzai ,banzai !!!!!

Repository:

Repository modules are responsible for handling data operations.

They provide a clean API to the rest of the app.

They know where to get the data from and what API calls to make when data is updated.

. You can consider them as mediators between different data sources (persistent model, web service, cache, etc.).

Android Application Architecture

Code:-

public class UserRepository {

private Webservice webservice; // Webservice UDF class for retrofit api

// ...

public LiveData getUser(int userId) {

// This is not an optimal implementation, we'll fix it below

final MutableLiveData data = new MutableLiveData<>();

webservice.getUser(userId).enqueue(new Callback() {

@Override

public void onResponse(Call call, Response response) {

// error case is left out for brevity

data.setValue(response.body());

}

});

return data;

}

}

Dude but what is the purpose ?

it abstracts the data sources from the rest of the app

Now our ViewModel does not know that the data is fetched by the Webservice,

which means we can swap it for other implementations as necessary.

Seite 3

Managing dependencies between components:

problem -

in normal implementation every repository class need to create object of API class and must fulfill their dependencies(reffer their library classes)

This would significantly complicate and duplicate the code

If each class creates a new WebService, it would be very resource heavy.

Two ways to solve the problem:

Dependency Injection:

def-dependency injection is a technique whereby one object supplies the dependencies of another object. A dependency is an object (in this case service api object )that can be used (a service). An injection is the passing of a dependency(which is an object) to a dependent object (a client) that would use it. The service is made part of the client's state.

Three types of injection:

1.Constructor injection

This method requires the client to provide a parameter in a constructor for the dependency.

// Constructor

Client(Service service) {

// Save the reference to the passed-in service inside this client

this.service = service;

}

2.Setter injection

This method requires the client to provide a setter method for the dependency.

// Setter method

public void setService(Service service) {

// Save the reference to the passed-in service inside this client

this.service = service;

}

3.Interface injection

This is simply the client publishing a role interface to the setter methods of the client's dependencies. It can be used to establish how the injector should talk to the client when injecting dependencies.

// Service setter interface.

public interface ServiceSetter {

public void setService(Service service);

}

// Client class

public class Client implements ServiceSetter {

// Internal reference to the service used by this client.

private Service service;

// Set the service that this client is to use.

@Override

public void setService(Service service) {

this.service = service;

}

}

-recommend Google's Dagger 2 library for implementing dependency injection in Android apps.

Service Locator: Service Locator provides a registry where classes can obtain their dependencies instead of constructing them. It is relatively easier to implement than Dependency Injection (DI), so if you are not familiar with DI, use a Service Locator instead.

Using Dagger 2:

Now we modify our UserProfileViewModel to use the repository.

public class UserProfileViewModel extends ViewModel {

private LiveData user;

private UserRepository userRepo;

@Inject // UserRepository parameter is provided by Dagger 2

public UserProfileViewModel(UserRepository userRepo) {

this.userRepo = userRepo;

}

public void init(String userId) {

if (this.user != null) {

// ViewModel is created per Fragment so

// we know the userId won't change

return;

}

user = userRepo.getUser(userId);

}

public LiveData getUser() {

return this.user;

}

}

whats in the nutshell :

make repository singleton class and use Dagger to get Repository object inside your ViewModel.

What i got in the end ?

- there will be only one object of repository through out the application means all every activity will refer only one repository object, So once you get data in repository whole application can access it. no need to create object of repository every time and get data using services for different object of repository.

- Use caching so you need to call services for only one time.

Seite 4

Caching the data :

Nothing is good when you relies only on one datasourse (it can ditch you like a bitch).well real reason is you you need to go through all this process of calling API or db,not very good and

it wastes valuable network bandwidth

forces the user to wait for the new query to complete.

Be safe use Cache !

Seite 5

Persisting Data:

Case 1 : user rotates screen or leaves app and comes back

->Cache can save you

Case 2 : if user leaves for hours and come back. android kills process

-> call service again or have some persistent data storage

->another way is caching is web request caching

In memory cache vs Web req. cache-

in memory cache are are killed when process dies

web req cache has time specified by server so it remains in memory for that much time.

Informationen

Beschreibung
Coding Notiz am Android Application Architecture, erstellt von vishal bhalerao am 30/09/2017.
Erstellt von
vishal bhalerao · Sep 2017
Aktualisiert
3 Feb 2018
Aufrufe
0
Bewertung

Feedback

Worum geht es?

Wie gefällt dir das neue Design?

Dein Eindruck