Giter VIP home page Giter VIP logo

android-build-an-app-architecture-components's Introduction

Sunshine with Architecture Components (DEPRECATED)

This Sample is Deprecated

This sample is deprecated and is not actively maintained. For example, the WorkManager library is now the best practice solution for handling scheduled background work.

Instead, please refer to the following samples and training materials:

About

This app is for the Build an App with Architecture Components Codelab.

Starting Classes

Below is a description of the different packages and classes in the starting app code.

data package

Contains all classes related to local and network app data.

data.network package

All classes related to fetching data from the network.

  • The network fetching and parsing functions are all written for you.
  • You will not modify the NetworkUtils, OpenWeatherJsonParser and WeatherResponse classes.
  • WeatherNetworkDataSource manages everything to do with the network. It's a singleton. It contains:
    • scheduleRecurringFetchWeatherSync() - Makes a repeating JobService using FirebaseJobDispatcher. This repeating job will eventually sync weather information in the background.
    • startFetchWeatherService() - IntentService for doing an immediate fetch of weather data.
    • fetchWeather() - Actually gets weather forecast data. This method uses the JSON parsing classes and network classes to make the fetch. It currently doesn't do anything with the fetched weather data.
data.database package

All classes related to caching the data locally (it's pretty empty right now).

  • WeatherEntry - A simple Java object representing one day of weather.

ui package

All activities and adapters - anything to do with display.

ui.detail package
  • DetailActivity - Activity for a single day of forecast.
ui.list package
  • MainActivty - Activity for a list of WeatherEntry forecasts.
  • ForecastAdapter - RecyclerView.Adapter for displaying the list of WeatherEntry forecasts.

utilities package

  • You will not modify SunshineDateUtils or SunshineWeatherUtils.
  • SunshineDateUtils - Utility methods for normalizing dates across time zones; this helps us to "round" to the nearest date, so that when you store a date in the database, it always refers to that date at 12:00am, GMT.
  • SunshineWeatherUtils - Utility methods related to displaying the weather, such as picking the right image resource to show a cloudy sky or rain.

AppExectuors class

This class provides a global executor pool. You can learn more about thread pools here. In short, this class provides an easy and efficient way to run code off of the main thread.

License

All image and audio files (including *.png, *.jpg, *.svg, *.mp3, *.wav and *.ogg) are licensed under the CC-BY-NC license. All other files are licensed under the Apache 2 license. See the LICENSE file for details. Copyright 2017 Google Inc. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

android-build-an-app-architecture-components's People

Contributors

ceruleanotter avatar naokigoogle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

android-build-an-app-architecture-components's Issues

Application crashing

On step 9, you are including the following dependencies for lifecycle:

compile "android.arch.lifecycle:runtime:1.0.0-alpha9"
compile "android.arch.lifecycle:extensions:1.0.0-alpha9"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha9"

but with this libreries the postValue() make my application crash, instead of this I use:

implementation "android.arch.lifecycle:runtime:1.0.0"
implementation "android.arch.lifecycle:extensions:1.0.0"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0"

and i change again DetailActivity extends from AppCompatActivity instead of LifecycleActivity, because on this version is deprecated.

If his problem is also fixed, could you please, update this tutorial?

Typo - 11. Create the Repository to Fetch and Save Data

Hi!

In the section titled "Your Turn: Complete the logic for fetching data", step 3, It says the following

In SunshineSyncIntertService, in onHandleIntent(), call the WeatherNetworkDataSource's fetchWeather() method.

When it should say

In SunshineSyncIntentService, in onHandleIntent(), call the WeatherNetworkDataSource's fetchWeather() method.

LifecycleActivity can no longer be used as an extension

In lesson 9: Intro to ViewModels and LiveData, step 4 says "Open ui.detail.DetailActivity. Have DetailActivity extend LifecycleActivity instead of AppCompatActivity." LifecycleActivity is now a component of AppCompatActivity. Extending LifecycleActivity will produce compile errors.

Step 12: What are ViewModelProvider factories for?

Sorry if this may seem too basic, but I can't wrap my head around the concept of ViewModelProvider factories. Why do we need factories? And is this the only way to create viewmodels in an activity? Thanks

9. Introduction to LiveData and ViewModels

Your Turn: The DetailActivityViewModel

  1. Open ui.detail.DetailActivity. Have DetailActivity extend LifecycleActivity instead of AppCompatActivity.

is there any activity name LifecycleActivity?

AppExecutors Class "Race condition"

My issue addresses the part in the class named "AppExecutors", at line 47 there is a method named "getInstance", at the section :
public static AppExecutors getInstance() { if (sInstance == null) { synchronized (LOCK) { sInstance = new AppExecutors(Executors.newSingleThreadExecutor(), Executors.newFixedThreadPool(3), new MainThreadExecutor()); } } return sInstance; }

This synchronized block does not actually avoid the race condition; consider the following scenario :
Thread 1 & Thread 2, they both call "getInstance" method at the same exact time for the very first time, then both will evaluate "if (sInstance == null)" to be True, thus the first one to acquire the lock will instantiate "sInstance" and then the other thread will acquire the lock afterwards thus, re-instantiating the "sInstance" variable once again, which is what we were trying to avoid in the first place.

So, to only instantiate "sInstance" only exactly once no matter what, you could either swap the condition line with the synchronized line like so :
synchronized (LOCK) { if (sInstance == null) { sInstance = new AppExecutors(Executors.newSingleThreadExecutor(), Executors.newFixedThreadPool(3), new MainThreadExecutor()); } }

Or to actually remove the synchronized block altogether and just make the whole function Synchronized like so :
synchronized public static AppExecutors getInstance() { if (sInstance == null) { sInstance = new AppExecutors(Executors.newSingleThreadExecutor(), Executors.newFixedThreadPool(3), new MainThreadExecutor()); } return sInstance; }

This will ensure 100% that "sInstance" will only be instantiated exactly once.

Thanks for your support.

Typo in html

In step 9 -> under LiveData -> in the 6th paragraph -> Second sentence: The period at the end of this sentence is delimited as ., instead of a regular period.

Step 9, LifecycleActivity

Since the January 22, 2018 release of Architecture components, LifecycleActivity is deprecated.

The build.gradle file can be updated to:

implementation "android.arch.lifecycle:runtime:1.1.1"
implementation "android.arch.lifecycle:extensions:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"

and at point 4.) Open ui.detail.DetailActivity. Have DetailActivity extend LifecycleActivity instead of AppCompatActivity. we should just keep it AppCompatActivity

Typo: WeahterDao

There is a typo in https://codelabs.developers.google.com/codelabs/build-app-with-arch-components/index.html?index=..%2F..%2Findex#11:

The WeatherDao returns the data you want and you could have the DetailActivityViewModel communicate directly with the WeahterDao. But that defeats the whole point of the repository class; the repository should be the single source of truth for all data operations. Therefore the DetailActivityViewModel will get this data from the SunshineRepository. The SunshineRepository will, in turn, ask the WeatherDao for the LiveData:

Manifest merger failed

This is what I get when I Try to Build the project

Manifest merger failed : Attribute meta-data#android.support.VERSION@value value=(26.0.1) from [com.android.support:preference-v7:26.0.1] AndroidManifest.xml:25:13-35
	is also present at [com.android.support:support-core-utils:26.1.0] AndroidManifest.xml:28:13-35 value=(26.1.0).
	Suggestion: add 'tools:replace="android:value"' to <meta-data> element at AndroidManifest.xml:23:9-25:38 to override.

Race Condition in SunshineRepository.getInstance

There is a race condition in the getInstance method in SunshineRepository.java.

Imagine there are 2 threads - A and B - both calling getInstance() and that sInstance is null to start with

Thread A
Checks if sInstance is null. Returns True

Thread B
Checks if sInstance is null. Returns True

Thread A
Obtains the lock and creates a new instance for sInstance. Releases lock

Thread B
Remember Thread B already checked if sInstance was null earlier.
Obtains the lock and creates a new instance for sInstance. Releases lock

There should be a second null check inside the synchronized block.

11. Create the Repository to Fetch and Save Data

This pertains to the lesson text and not the code (code compiles and runs just fine).

Near the end of the lesson for Step 11, after observing the logs.

"2. When SunshineData.intializeData() is called"

This may be incorrect.  Shouldn't "SunshineData"be "SunshineRepository" like this?

"2. When SunshineRepository.intializeData() is called"

Typo in instruction

  • In step 13, there is first sub point which is "doa" instead of "dao".
  • In step 16, there are all bullet points, in which "Steps:" in also bullet point. It should be without bullet because it denotes that below in steps.

Thanks

Initial Setup: Manifest Merger Failed

Needed to add this to the bottom of the module app build.gradle
Android Studio 3.1.2

configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        def requested = details.requested
        if (requested.group == 'com.android.support') {
            if (!requested.name.startsWith("multidex")) {
                details.useVersion '26.1.0'
            }
        }
    }
}

Small typo in the instruction (step 14)

in step 14 when you're about to go through the steps, the first point says:

Make new doa command for a list of forecasts after a date

I think this is supposed to be dao? maybe you could just call it Dao :)

Then this point:

Also make a factory, you can model this off of the detail view model factor almost entirely

factor == factory?

also suggest view model to be ViewModel as this is already in the context of android :)

Uncomment injector utils

== Uncomment InjectorUtils ?

hope this helps with the doc.

Wrong variable type in the diagram

The variable type mentioned in the diagram is LiveData<List<List>> while it should have been LiveData<List> in MainActivityViewModel Box .

Link to "Indices" Broken

Under "Create an Entity", the third step ("The date field should be unique") has a hyperlink on "Indices." However, this merely links to the landing page for Room.
As the link above does not talk in specific about indices, would this be the intended link for indices in Room? If you could confirm on the link, I will be happy to raise a PR with the fix.
Thanks! :)

How should we mock the room database and dao's?

I've found no example code available from google (or anyone) of unit tests that depend on mocking the Room database and tightly coupled dao objects:
SunshineDatabase.getInstance(context).weatherDao();
Note: I'm explicitly not talking about instrumented tests.

I used PowerMock(ito) to mock the canonical RoomDatabase.getInstance() static method at the heart of it all. Is this the best way? Or is it skipped because Dagger2 is the preferred way, and that is deemed to complex for these example apps?

Either way, please add best practice examples of unit testing Room with mocks, whether it be with dependency injection or mocking the static getInstance() method.

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.