LiveCycle Scheitert

  • Antworten:10
  • OffenNicht stickyBentwortet
  • Forum-Beiträge: 427

23.05.2021, 18:02:21 via Website

Hallo zusammen

Ich versuche mich in Kotlin zu verbessern. Dazu arbeite ich mich durch ein Buch.
Das Beispiel, welches das Livecycle demonstriert, funktioniert bei mir nicht. Beim Compilieren entsteht folgender Fehler :

Duplicate class android.support.v4.app.INotificationSideChannel found in modules core-1.5.0-runtime (androidx.core:core:1.5.0) and support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)

und

Duplicate class android.support.v4.app.INotificationSideChannel found in modules core-1.5.0-runtime (androidx.core:core:1.5.0) and support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)
Duplicate class android.support.v4.app.INotificationSideChannel$Stub found in modules core-1.5.0-runtime (androidx.core:core:1.5.0) and support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)
Duplicate class android.support.v4.app.INotificationSideChannel$Stub$Proxy found in modules core-1.5.0-runtime (androidx.core:core:1.5.0) and support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)
Duplicate class android.support.v4.os.IResultReceiver found in modules core-1.5.0-runtime (androidx.core:core:1.5.0) and support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)
Duplicate class android.support.v4.os.IResultReceiver$Stub found in modules core-1.5.0-runtime (androidx.core:core:1.5.0) and support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)
Duplicate class android.support.v4.os.IResultReceiver$Stub$Proxy found in modules core-1.5.0-runtime (androidx.core:core:1.5.0) and support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)
Duplicate class android.support.v4.os.ResultReceiver found in modules core-1.5.0-runtime (androidx.core:core:1.5.0) and support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)
Duplicate class android.support.v4.os.ResultReceiver$1 found in modules core-1.5.0-runtime (androidx.core:core:1.5.0) and support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)
Duplicate class android.support.v4.os.ResultReceiver$MyResultReceiver found in modules core-1.5.0-runtime (androidx.core:core:1.5.0) and support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)
Duplicate class android.support.v4.os.ResultReceiver$MyRunnable found in modules core-1.5.0-runtime (androidx.core:core:1.5.0) and support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)

Go to the documentation to learn how to Fix dependency resolution errors.

Leider ist der Link nicht so aussage kräftig. Ich habe alle meine Codedateien zwei mal überprüft. Ich habe nichts anderes drin als das was im Buch steht. Und trotzdem funktioniert es nicht. Mein Problem ist, wo soll ich den Fehler suchen gehen. Am Code kann es nicht liegen, denn da wird nichts rot unterlegt.

Darum Meine Frage :
Wo soll ich nach einem möglichen Fehler suchen?

Gruss Renato

Vielleicht doch noch den Code. Könnte sein, dass ich doch was falsch gemacht habe.

MainActivity:

package ch.robbisoft.stopwatchdemo

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import ch.robbisoft.stopwatchdemo.databinding.ActivityMainBinding
import java.text.SimpleDateFormat
import java.util.*

class MainActivity : AppCompatActivity() {

private val dateFormat = SimpleDateFormat("HH:mm:ss:SSS", Locale.US)

init {
    dateFormat.timeZone = TimeZone.getTimeZone("UCT")
}

private val model : StopWatchDemoViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    val observer = StopWatchDemoLifecycleObserver(model)
    model.running.observe(this, { running : Boolean? ->
        running?.let {
            binding.btnStart.setText(if (it) R.string.stop else R.string.start)
            binding.btnStop.isEnabled = !it
        }
    })

    model.diff.observe(this){ diff : Long? ->
        diff?.let{
            binding.txtMain.text = dateFormat.format(Date(it))
        }
    }

    binding.btnStart.setOnClickListener {
        model.running.value?.let { running ->
            if(running){
                observer.stop()
            }else{
                observer.scheduleAtFixedRate()
            }
            model.running.value = !running
        }
    }

    binding.btnStop.setOnClickListener { model.diff.setValue(0L) }
    lifecycle.addObserver(observer)
}

}

StopWatchDemoLifecycleObserver Klasse :

package ch.robbisoft.stopwatchdemo

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import java.util.*

class StopWatchDemoLifecycleObserver internal constructor(private val model : StopWatchDemoViewModel) : LifecycleObserver{

private lateinit var timer : Timer
private lateinit var timerTask : TimerTask

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun startTimer(){
    timer = Timer()
    val running = model.running.value ?: false
    if (running){
        scheduleAtFixedRate()
    }
}

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun stopTimer() {
    timer.cancel()
}

fun stop(){
    timerTask.cancel()
}

fun scheduleAtFixedRate(){
    val now = System.currentTimeMillis()
    val diff = model.diff.value ?: now
    model.started.value = now - diff
    timerTask = object : TimerTask(){
        override fun run() {
            model.started.value?.let{
                model.diff.postValue(System.currentTimeMillis() - it)
            }
        }
    }
    timer.scheduleAtFixedRate(timerTask, 0, 200)
}

}

StopWatchDemoViewModel Klasse :

package ch.robbisoft.stopwatchdemo

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class StopWatchDemoViewModel : ViewModel() {
val running = MutableLiveData(false)
val diff = MutableLiveData(0L)
val started = MutableLiveData(0L)
}

Diskutiere mit!
Beste Antwort
  • Forum-Beiträge: 427

23.05.2021, 21:43:33 via Website

Problem gelöst!

Ich habe bei "gradle.properties" die Zeile "android.enableJetifier=true" eingefügt. Und nun funktioniert es.
Ich weiss zwar nicht warum aber es funktioniert. Das ist die Hauptsache.

Gruss Renato

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 11.184

23.05.2021, 18:26:10 via Website

Hallo Renato,

der Duplicate class Fehler ist doch eindeutig:

Duplicate class android.support.v4.app.INotificationSideChannel found in modules core-1.5.0-runtime (androidx.core:core:1.5.0) and support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)

Du hast supportv4 Lib und androidx.core eingebunden, der Fehler bedeutet, dass es eine Klasse die gleich heißt (Package) in beiden Libs gibt und das darf nicht sein.
Wenn du androidx nutzt, darfst du keine "alten" Support Libs mehr haben.
Also dependency enfernen und evenutelle Abhängigkeiten auf AndroidX updaten.

Den wichtigsten Hinweis hast du wohl übersehen:
Go to the documentation to learn how to Fix dependency resolution errors.

— geändert am 23.05.2021, 18:27:37

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 427

23.05.2021, 20:05:48 via Website

Ciao Pascal

Ich kann dir leider nicht folgen. Was soll ich wo entfernen?

androidx.core:core:1.5.0

Habe ich in Build.gradle gefunden und entfernt. Danach eine migration auf androidx gemacht. Es erscheint aber immer noch denselben Fehler. Wo finde ich "dependency", welches ich entfernen muss?

Den Link habe ich nicht übersehen. Aber bei mir erscheint die Webseite nur zur Hälfte. Die linke Seite wird vom Menü überdeckt, so dass ich nicht an die nötigen Informationen komme. Scrollen geht auch nicht.

Gruss Renato

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 427

23.05.2021, 21:28:15 via Website

Ich komme nicht weiter. Der Fehler besteht immer noch. Meine build.gradle sieht wie folgt aus.

plugins {
id 'com.android.application'
id 'kotlin-android'

}

android {
compileSdkVersion 30
buildToolsVersion "30.0.3"

buildFeatures {
    viewBinding = true
}

defaultConfig {
    applicationId "ch.robbisoft.stopwatchdemo"
    minSdkVersion 21
    targetSdkVersion 30
    versionCode 1
    versionName "1.0"

    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}
compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
    jvmTarget = '1.8'
}

}

dependencies {

implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}"
implementation 'androidx.core:core-ktx:1.5.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

implementation "android.arch.lifecycle:extensions:1.1.1"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"
implementation "androidx.fragment:fragment-ktx:1.3.4"

testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

}

Wenn ich was entferne wird es nicht besser. Oder was muss ich entfernen?

Gruss Renato

Hilfreich?
Diskutiere mit!
Beste Antwort
  • Forum-Beiträge: 427

23.05.2021, 21:43:33 via Website

Problem gelöst!

Ich habe bei "gradle.properties" die Zeile "android.enableJetifier=true" eingefügt. Und nun funktioniert es.
Ich weiss zwar nicht warum aber es funktioniert. Das ist die Hauptsache.

Gruss Renato

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 1.441

23.05.2021, 23:27:28 via Website

Hallo Renato

implementation "android.arch.lifecycle:extensions:1.1.1"

brauchst du nicht, das ist aus der Support Lib
du hast doch schon von androidX

implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"

was genau das gleiche ist.

Ich weiss zwar nicht warum aber es funktioniert. Das ist die Hauptsache.

nicht unbedingt.
Wenn du nicht weist was der Gradle Schalter macht dann schlage es nach.
https://stackoverflow.com/questions/51680671/what-is-jetifier

— geändert am 23.05.2021, 23:50:56

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 427

24.05.2021, 18:41:02 via Website

Ciao Jokel

Da hat sich mal wieder im Buch ein Fehler eingeschlichen. Danke Jokel für den Tipp.

Gruss Renato

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 1.441

24.05.2021, 20:03:52 via Website

Hallo
Dein Buch wird wohl etwas älter sein und noch mit Support Libs arbeiten.
Nicht wie jetzt üblich AndroidX.

Hilfreich?
Diskutiere mit!