Coder Social home page Coder Social logo

codelab-android-room-with-a-view's Introduction

RoomWordsSample

This repository contains the finished sample code for the Architecture Components codelab in Java on the master branch and in Kotlin for the Architecture Components Kotlin codelab on the kotlin branch.

Introduction

In May 2017 Google released the Architecture Components libraries. Each library manages and simplifies aspects of data persistence and the UI component lifecycle. Together, the libraries encourage a modular app architecture that results in reduced complexity and less code.

This sample shows how to use the libraries to build a complete basic app that implements the recommended architecture and can be used as a template for further explorations.

Pre-requisites

  • Android Studio 3.0 or later and you know how to use it.

  • Make sure Android Studio is updated, as well as your SDK and Gradle. Otherwise, you may have to wait for a while until all the updates are done.

  • A device or emulator that runs SDK level 20

You need to be solidly familiar with the Java programming language, object-oriented design concepts, and Android Development Fundamentals. In particular:

  • RecyclerView and Adapters
  • SQLite database and the SQLite query language
  • Threading and ExecutorService
  • It helps to be familiar with software architectural patterns that separate data from the user interface, such as MVP or MVC. This codelab implements the architecture defined in the Guide to App Architecture

Getting Started

  1. Install Android Studio, if you don't already have it.
  2. Download the sample.
  3. Import the sample into Android Studio.
  4. Build and run the sample.

License

Copyright 2019 Google, Inc.

All image and audio files (including *.png, *.jpg, *.svg, *.mp3, *.wav and *.ogg) are licensed under the CC BY 4.0 license. All other files are licensed under the Apache 2 license.

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the LICENSE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you 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.

codelab-android-room-with-a-view's People

Contributors

akshayjpatil avatar ceruleanotter avatar dagalpin avatar florina-muntenescu avatar tiembo 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  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

codelab-android-room-with-a-view's Issues

Room version control question

There is a possibility to pass as a parameter the version of the database in

@Database (entities = arrayOf (Vehicle :: class), version = versionCode, exportSchema = true)

Codelab WordViewModel class issue.

In the WordViewModel ( kotlin version code) we are having private val repository: WordRepository so the repository not accessible in the following line.

fun insert(word: Word) = viewModelScope.launch {
        repository.insert(word)
    }

Compilation error
Any suggestions for the fixes or workaround for the mentioned issue.

AndroidViewModel requires ViewModelProvider.Factory

Add this class:
class MyViewModelFactory (private var application: Application): ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class): T {
return modelClass.getConstructor(Application::class.java).newInstance(application)
}
}
and this line to MainActivity:
val viewModelFactory = MyViewModelFactory(application)

Floating Action Button: fab is not declared

In Kotlin codelab example: https://codelabs.developers.google.com/codelabs/android-room-with-a-view-kotlin/#13

In Connect With the Data section, in Finished Code panel, in onCreate, Floating Action Button fab has not been declared but used directly to set onclick listener.

class MainActivity : AppCompatActivity() {

   private const val newWordActivityRequestCode = 1
   private lateinit var wordViewModel: WordViewModel

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
       setSupportActionBar(toolbar)

       val recyclerView = findViewById<RecyclerView>(R.id.recyclerview)
       val adapter = WordListAdapter(this)
       recyclerView.adapter = adapter
       recyclerView.layoutManager = LinearLayoutManager(this)

       wordViewModel = ViewModelProviders.of(this).get(WordViewModel::class.java)
       wordViewModel.allWords.observe(this, Observer { words ->
           // Update the cached copy of the words in the adapter.
           words?.let { adapter.setWords(it) }
       })

       fab.setOnClickListener {
           val intent = Intent(this@MainActivity, NewWordActivity::class.java)
           startActivityForResult(intent, newWordActivityRequestCode)
       }
   }

   override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
       super.onActivityResult(requestCode, resultCode, data)

       if (requestCode == newWordActivityRequestCode && resultCode == Activity.RESULT_OK) {
           data?.let {
               val word = Word(it.getStringExtra(NewWordActivity.EXTRA_REPLY))
               wordViewModel.insert(word)
           }
       } else {
           Toast.makeText(
               applicationContext,
               R.string.empty_not_saved,
               Toast.LENGTH_LONG).show()
       }
   }
}

The Kotlin version has a Java example in Step 4

The Step 4 (Create an Entity) has a Tip block at the end which contains a Java example, even though the CodeLab is specific for Kotlin.

The snippet of Java Code can be confusing to newcomers as it actually contradicts the paragraph above it (where it says that "Every property that's stored in the database needs to have public visibility"). And the snipped shows private Java properties being annotated.

ViewModelProvider vs ViewModelProviders

Android Room with a View - Kotlin, 14. Connect with the data.

The first example of using the ViewModelProvider uses the following line of code "wordViewModel = ViewModelProvider(this).get(WordViewModel::class.java)" which is wrong.

While the complete example uses the following line " wordViewModel = ViewModelProviders.of(this).get(WordViewModel::class.java)" which works properly.

Wrong Dependencie Version for Lifecycle

Hi,

when you try to copy and paste to code, it will not work, since the Constructor of ViewModelProvider does not exists.
myViewModel = new ViewModelProvider(this).get(MyViewModel.class);

You have to chance the dependency-version to
archLifecycleVersion = '2.2.0-beta01'
as it is written in the src code, but not in the CodeLab.

unknown property coroutines

I get the above error at step 3 when I try to sync the project. It's complaining about the build gradle project file.

Final Code in "Populate the database" needs correction

Code in final code within "Populate the database" needs correction as follows

`// Annotates class to be a Room Database with a table (entity) of the Word class
@database(entities = arrayOf(Word::class), version = 1, exportSchema = false)
public abstract class WordRoomDatabase: RoomDatabase() {

abstract fun wordDao(): WordDao

private class WordDatabaseCallback(
    private val scope: CoroutineScope
) : RoomDatabase.Callback() {

    override fun onOpen(db: SupportSQLiteDatabase) {
        super.onOpen(db)
        INSTANCE?.let { database ->
            scope.launch {
                populateDatabase(database.wordDao())
            }
        }
    }

    suspend fun populateDatabase(wordDao: WordDao) {
        // Delete all content here.
        wordDao.deleteAll()

        // Add sample words.
        var word = Word("Hello")
        wordDao.insert(word)
        word = Word("World!")
        wordDao.insert(word)

        // TODO: Add your own words!
        word = Word("TODO!")
        wordDao.insert(word)
    }
}


companion object {
    // Singleton prevents multiple instances of database opening at the
    // same time.
    @Volatile
    private var INSTANCE: WordRoomDatabase? = null

    fun getDatabase(
        context: Context,
        scope: CoroutineScope
    ): WordRoomDatabase {

        // if the INSTANCE is not null, then return it,
        // if it is, then create the database
        return INSTANCE ?: synchronized(this) {
            val instance = Room.databaseBuilder(
                context.applicationContext,
                WordRoomDatabase::class.java,
                "word_database"
            )
                .addCallback(WordDatabaseCallback(scope))
                .build()
            INSTANCE = instance
            // return instance
            instance
        }
    }
}

}`

Step 9. Create the ViewModel

This line is not updated with the coroutine parameter in method getDatabase()
val wordsDao = WordRoomDatabase.getDatabase(application).wordDao()

A constant declared without being initialized.

A Constant should be initialized when being declared and Constant cannot be reinitialized as done in this code.

In this use case, wordItemView must not be a constant.

private final TextView wordItemView;

 private WordViewHolder(View itemView) {
           super(itemView);
           wordItemView = itemView.findViewById(R.id.textView);
       }

Nullable String warning in `OnActivityResult` sample

In the Connect with the data step, the following sample is given:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  // ...
  val word = Word(it.getStringExtra(NewWordActivity.EXTRA_REPLY))
  // ...
}

I get a warning for this code:

Type mismatch: inferred type is String? but String was expected

Typo Mistake

In Android Room with a View - Java web page, there is a statement

You need to be familiar with Kotlin, object-oriented design concepts, and Android Development Fundamentals. In particular:

This can be confusing to readers.

Redundant style attributes

In step 10("Add XML layout") of the codelab style is being created including android:layout_width attribute. Then view was added into the recyclerview_item.xml file with the same attribute. It can be confusing for newbies. An attribute should be deleted from style.

Incorrect reference in SQL statement on step 4 and 14

Incorrect SQL statement on steps 4 (Create the Dao) and in referencing on step 14 (Summary). Referencing to "word" errors. Otherwise, I was able to run this app tutorial successfully on the current tutorial version (as of 1/7/2020). I'm coding Java not Kotlin.

Incorrect: "SELECT * from word_table ORDER BY word ASC"
Correct: "SELECT * from word_table ORDER BY mWord ASC" <-- word to mWord

Should be using 2 fragments with an activity-scoped shared ViewModel instead of passing stuff around in `onActivityResult`

Using onActivityResult in https://codelabs.developers.google.com/codelabs/android-room-with-a-view-kotlin/index.html?index=..%2F..index#13 bypasses the original premise of ViewModel described in https://codelabs.developers.google.com/codelabs/android-lifecycles/#5 and is therefore not the best way to represent how to use AAC.

Especially considering that the Android Persistence Codelabs was deprecated in favor of this codelabs (googlecodelabs/android-persistence#27) and should represent Best Practices.

Currently, this Codelabs does not actually represent the AAC best practices, and this should be fixed. With this flaw, I can't in good conscience link this to any beginners at the moment (without adding the footnote to "beware the 13-14th steps").

Manifest merger failed : Attribute application@appComponentFactory

last 3 day i am showing this problem,how can i solve it.this problem here

Manifest merger failed : Attribute application@appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91
is also present at [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 value=(androidx.core.app.CoreComponentFactory).
Suggestion: add 'tools:replace="android:appComponentFactory"' to element at AndroidManifest.xml:5:5-21:19 to override.

i am using this gradle

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'

android {
compileSdkVersion 28
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.mohoshin.myapplication"
minSdkVersion 17
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.google.firebase:firebase-database:19.0.0'

implementation 'com.google.firebase:firebase-core:17.2.0'
implementation 'com.google.firebase:firebase-messaging:20.0.0'



testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

}

ViewModelProvider constructors

Room with a View, Java version - step 14, Connect with the data.

mWordViewModel = new ViewModelProvider(this).get(WordViewModel.class);

results in 'error: no suitable constructor found for ViewModelProvider(MainActivity)'. Looks like ViewModelProvider has two constructors, but both have two arguments, not one. I'm guessing MainActivity can be implicitly casted to ViewModelStoreOwner, but I can't see what's missing for the second argument.

when i use this room framework, it always show the error

Could not resolve all files for configuration ':data:debugAnnotationProcessorClasspath'.
Could not download kotlinx-metadata-jvm.jar (org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.0.5)
Could not get resource 'https://jcenter.bintray.com/org/jetbrains/kotlinx/kotlinx-metadata-jvm/0.0.5/kotlinx-metadata-jvm-0.0.5.jar'.
Could not GET 'https://jcenter.bintray.com/org/jetbrains/kotlinx/kotlinx-metadata-jvm/0.0.5/kotlinx-metadata-jvm-0.0.5.jar'.

Use ViewModel constructor instead of ViewModelProvider

In order to use queries with parameter I didn't find any solution so I tried to create another constructor for both view model class and repository class but I noticed that in CodeLab they don't use view model constructors at all and instead they use view model provider so I changed it and used this : new StoryViewModel(getApplication(),"Fiction"); instead of this: new ViewModelProvider(this).get(StoryViewModel.class);
I don't know if there's anything wrong with this or not. It works fine now, but if it's the way why didn't we use this always? and why do we use view model provider?
Can anyone explain?
Or help me with using queries with parameter.

Thank you.

Data is not persistent

As this is a Room example it is very frustrating to see, the data is not stored.

Every time the program is restartet, the data is lost.

I downloaded the database from the emulator which does not seem to have any contents.

I do not get any errors in LogCat and the insert statement finishes OK.

For tests I use this github repository, same with manually created in tutorial.

Nexus 5 Emulator with API 26 and 28.

Codelab documentation imports wrong RecyclerView

This is not a problem with this repository but a problem with the CodeLab for this project. I didn't know where else to report this. On Step 10 of the code lab they tell you to copy/paste in a RecyclerView, but it is from the wrong library. The project should use the androidx version, as is used in this repository.

Issue on this page:
https://codelabs.developers.google.com/codelabs/android-room-with-a-view/#9

From Code Lab in above link:

Replace:
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/darker_gray"
tools:listitem="@layout/recyclerview_item" />

with:
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/darker_gray"
tools:listitem="@layout/recyclerview_item" />

The Database Creation code in Step 7 is not actually thread safe

Currently, step 7 includes the following code for creating a Database:

// Annotates class to be a Room Database with a table (entity) of the Word class
@Database(entities = arrayOf(Word::class), version = 1, exportSchema = false)
public abstract class WordRoomDatabase : RoomDatabase() {

   abstract fun wordDao(): WordDao

   companion object {
        // Singleton prevents multiple instances of database opening at the
        // same time. 
        @Volatile
        private var INSTANCE: WordRoomDatabase? = null

        fun getDatabase(context: Context): WordRoomDatabase {
            val tempInstance = INSTANCE
            if (tempInstance != null) {
                return tempInstance
            }
            synchronized(this) {
                val instance = Room.databaseBuilder(
                        context.applicationContext,
                        WordRoomDatabase::class.java, 
                        "word_database"
                    ).build()
                INSTANCE = instance
                return instance
            }
        }
   }
}

The problem with this code is that, theoretically, two threads could both get to the if statement in getDatabase at the same time. They would then both observe INSTANCE as being null and both go on to create their own database handles (albeit, they would do the creation one at a time).

WordListAdapter Method is Private

In my android studio it appears the default is to mark methods as private. So I had to do the following:

public WordListAdapter(Context context) { mInflater = LayoutInflater.from(context); }

LiveData with room

I'm not sure it's the problem with this demo but ... :)
I added stetho integration to this app and when app was running I addes some words to database using chrome (chrome://inspect). This new data appears in the app only when i rerun app - it's correct way how LiveData observers works ?

Dao getAllWords()

@dao
interface WordDao {

@Query("SELECT * from word_table ORDER BY word ASC")
fun getAllWords(): LiveData<List<Word>> //Correct
fun getAllWords(): List<Word> //Wrong

@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(word: Word)

@Query("DELETE FROM word_table")
suspend fun deleteAll()

}

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.