标签: android-livedata

错误:程序类型已存在:android.arch.lifecycle.LiveData

当我按下Android Studio中的播放按钮时,我的应用程序会编译,但会显示此错误(编辑):

错误:程序类型已存在:android.arch.lifecycle.LiveData

(完整日志)

我试过删除.gradle文件夹,然后去Build > Clean ProjectBuild > Rebuild Project.但是,它不起作用.我也尝试删除源代码,然后再次克隆git并将文件夹导入Android Studio.但是,它仍会产生该错误.

这是我的应用程序app/build.gradle:

Error:Program type already present: android.arch.lifecycle.LiveData
Run Code Online (Sandbox Code Playgroud)

android android-studio android-gradle-plugin android-livedata

26
推荐指数
3
解决办法
3万
查看次数

将 Jetpack Compose 升级到 1.0.0?beta07 后出现 java.lang.NoSuchMethodError

observeAsState将 Jetpack Compose 升级到 1.0.0?beta07 后,在 LiveData 对象上运行时出现以下错误。

java.lang.NoSuchMethodError: No interface method startReplaceableGroup(ILjava/lang/String;)V in class Landroidx/compose/runtime/Composer; or its super classes
Run Code Online (Sandbox Code Playgroud)

文档说升级时会出现错误,为了解决它,必须重新编译依赖于 Compose 的库。

我不知道必须这样做。我尝试再次制作该项目,也无济于事地清除和重建它。

这是我项目中的依赖项:

dependencies {
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
    implementation "androidx.compose.ui:ui-tooling:$compose_version"
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0-alpha01'
    implementation 'androidx.activity:activity-compose:1.3.0-alpha07'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
    implementation "io.github.vanpra.compose-material-dialogs:datetime:0.4.0"
    implementation "io.github.vanpra.compose-material-dialogs:datetime:0.4.0"
    implementation "androidx.appcompat:appcompat:$appCompatVersion"
    implementation "androidx.activity:activity-ktx:$activityVersion"
    implementation "androidx.room:room-ktx:$roomVersion"
    kapt "androidx.room:room-compiler:$roomVersion"
    androidTestImplementation "androidx.room:room-testing:$roomVersion"
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion"
    implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion"
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.30"
    api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines"
    api …
Run Code Online (Sandbox Code Playgroud)

android android-livedata android-jetpack-compose

24
推荐指数
2
解决办法
2880
查看次数

LiveData.getValue()在Room中返回null

Java POJO对象

public class Section {

    @ColumnInfo(name="section_id")
    public int mSectionId;

    @ColumnInfo(name="section_name")
    public String mSectionName;

    public int getSectionId() {
        return mSectionId;
    }

    public void setSectionId(int mSectionId) {
        this.mSectionId = mSectionId;
    }

    public String getSectionName() {
        return mSectionName;
    }

    public void setSectionName(String mSectionName) {
        this.mSectionName = mSectionName;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的查询方法

@Query("SELECT * FROM section")
LiveData<List<Section>> getAllSections();
Run Code Online (Sandbox Code Playgroud)

访问数据库

final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections();
Run Code Online (Sandbox Code Playgroud)

在下一行,我正在检查sections.getValue()哪个总是给我null,虽然我在DataBase中有数据,后来我得到了onChanged()方法中的值.

sections.observe(this, new Observer<List<Section>>() {
    @Override
    public void onChanged(@Nullable List<Section> sections){

    }
});
Run Code Online (Sandbox Code Playgroud)

但是当我从查询中省略LiveData时,我正在按预期获取数据.查询方法:

@Query("SELECT * …
Run Code Online (Sandbox Code Playgroud)

android android-room android-livedata android-architecture-components

23
推荐指数
2
解决办法
2万
查看次数

Kotlin Flow 与 LiveData

在上一次 Google I/O 大会上,Jose Alcerreca 和 Yigit Boyar告诉我们,我们不应再使用 LiveData 来获取数据。现在我们应该使用挂起函数进行一次性提取并使用 Kotlin 的 Flow 创建数据流。我同意协程非常适合一次性获取或其他 CRUD 操作,例如插入等。但是在我需要数据流的情况下,我不明白 Flow 给我带来了什么优势。在我看来,LiveData 也在做同样的事情。

流程示例:

视图模型

val items = repository.fetchItems().asLiveData()
Run Code Online (Sandbox Code Playgroud)

存储库

fun fetchItems() = itemDao.getItems()
Run Code Online (Sandbox Code Playgroud)

@Query("SELECT * FROM item")
fun getItems(): Flow<List<Item>>
Run Code Online (Sandbox Code Playgroud)

LiveData 示例:

视图模型

val items = repository.fetchItems()
Run Code Online (Sandbox Code Playgroud)

存储库

fun fetchItems() = itemDao.getItems()
Run Code Online (Sandbox Code Playgroud)

@Query("SELECT * FROM item")
fun getItems(): LiveData<List<Item>>
Run Code Online (Sandbox Code Playgroud)

我还想看到一些使用协程和 Flow 来处理 Room 或 Retrofit 的项目示例。我只找到了一个 Google 的ToDo 示例,其中协程用于一次性获取,然后在更改时手动重新获取数据。

android kotlin android-livedata kotlin-coroutines kotlinx.coroutines.flow

23
推荐指数
3
解决办法
6673
查看次数

具有多个参数的MediatorLiveData或switchMap转换

Transformations.switchMap在我的ViewModel中使用,因此LiveData在我的片段中观察到的我的集合会对code参数的变化做出反应.

这非常有效:

public class MyViewModel extends AndroidViewModel {

    private final LiveData<DayPrices> dayPrices;
    private final MutableLiveData<String> code = new MutableLiveData<>();
    // private final MutableLiveData<Integer> nbDays = new MutableLiveData<>();
    private final DBManager dbManager;

    public MyViewModel(Application application) {
        super(application);
        dbManager = new DBManager(application.getApplicationContext());
        dayPrices = Transformations.switchMap(
            code,
            value -> dbManager.getDayPriceData(value/*, nbDays*/)
        );
    }

    public LiveData<DayPrices> getDayPrices() {
        return dayPrices;
    }

    public void setCode(String code) {
        this.code.setValue(code);
    }

    /*public void setNbDays(int nbDays) {
        this.nbDays.setValue(nbDays);
    }*/

}

public class …
Run Code Online (Sandbox Code Playgroud)

android observer-pattern android-livedata android-viewmodel android-architecture-components

21
推荐指数
3
解决办法
9882
查看次数

MutableLiveData 未在 UI 中更新

更新: 如果我移动到另一个片段并返回到这个片段,TextView 会更新......

我无法通过使用 setValue() 或 postValue() 使 UI 中的 MutableLiveData 更新为新值。我可以通过将 MutableLiveData 更改为 ObservableData 来使其工作,但重点是使用 LiveData 而不是 ObservableData。

我在其他视图中也有类似的工作没有问题。不确定这里发生了什么......我唯一能想到的是我在相机活动(通过意图)和这个片段之间来回跳跃。在活动结果上,我将片段中的数据设置到 ViewModel。

我不相信我需要为片段中的值设置任何观察者,因为我在 XML 和 ViewModel 之间有 2 路数据绑定。

my_fragment.XML

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="myViewModel"
            type="com.example.myapplication.MyViewModel" />
    </data>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

            <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@={myViewModel.photosCount}"
            tools:text="1" />

           <Button
               android:id="@+id/btnTakePhoto"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:text="Take Picture"
               android:onClick="@{myViewModel::navClicked}"/>

    </LinearLayout>

</layout>
Run Code Online (Sandbox Code Playgroud)

视图模型.java

private MutableLiveData<String> photosCount = new MutableLiveData<>();
private MutableLiveData<Boolean> takePhoto = new MutableLiveData<>();

public MyViewModel() {
    photosCount.setValue("0"); // …
Run Code Online (Sandbox Code Playgroud)

android android-livedata mutablelivedata

20
推荐指数
3
解决办法
2万
查看次数

Android Room:更新插入的LiveData回调?

我有一个简单的DAO,包括CRUD功能

FeedEntryDAO.java

@Dao
public interface FeedEntryDAO {

  @Query("SELECT * FROM feedEntrys")
  LiveData<List<FeedEntry>> getAll();

  @Query("SELECT * FROM feedEntrys WHERE uid = :uid LIMIT 1")
  LiveData<FeedEntry> findByUid(int uid);

  @Insert
  void insertAll(FeedEntry... feedEntries);

  @Delete
  void delete(FeedEntry feedEntry);

  @Update
  int update(FeedEntry feedEntry);

}
Run Code Online (Sandbox Code Playgroud)

对于select,可以返回LiveData类型.

在Activity中,代码非常适合选择

viewModel.getFeedEntrys().observe(this,entries -> {...});
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试插入,更新,删除数据时.代码看起来有点难看,每次都会创建一个asynctask.

new AsyncTask<FeedEntry, Void, Void>() {
                @Override
                protected Void doInBackground(FeedEntry... feedEntries) {
                  viewModel.update(feedEntries[0]);
                  return null;
                }
}.execute(feedEntry);
Run Code Online (Sandbox Code Playgroud)

我有2个问题:

  1. 我可以使用LiveData来包装删除,插入,更新功能吗?
  2. 更好的方法是为删除,插入,更新维护这样的asynctask类?

感谢任何建议和意见.谢谢.

android android-room android-livedata android-architecture-components

19
推荐指数
2
解决办法
1万
查看次数

Room:来自Dao的LiveData将在每次更新时触发Observer.onChanged,即使LiveData值没有变化

我发现Dao返回的LiveData会在DB中更新行时调用它的观察者,即使LiveData值显然没有改变.

考虑类似以下示例的情况:

示例实体

@Entity
public class User {
    public long id;
    public String name;
    // example for other variables
    public Date lastActiveDateTime;
}
Run Code Online (Sandbox Code Playgroud)

示例道

@Dao
public interface UserDao {
    // I am only interested in the user name
    @Query("SELECT name From User")
    LiveData<List<String>> getAllNamesOfUser();

    @Update(onConflict = OnConflictStrategy.REPLACE)
    void updateUser(User user);
}
Run Code Online (Sandbox Code Playgroud)

某个地方在后台线程

UserDao userDao = //.... getting the dao
User user = // obtain from dao....
user.lastActiveDateTime = new Date(); // no change to user.name
userDao.updateUser(user);
Run Code Online (Sandbox Code Playgroud)

UI中的某个地方

// omitted ViewModel …
Run Code Online (Sandbox Code Playgroud)

android android-room android-livedata

18
推荐指数
2
解决办法
9726
查看次数

使用Kotlin扩展函数将RxJava Observable转换为实时数据

我一直在使用库在我的代码中使用很多RxJava Observables转换.所以我想在RxJava Observable中添加一个扩展函数来轻松转换它们.LiveDataLiveDataReactiveStreams.fromPublisher()LiveData

这些是我的扩展功能:

fun <T> Flowable<T>.toLiveData() :  LiveData<T> {
    return LiveDataReactiveStreams.fromPublisher(this)
}

fun <T> Observable<T>.toLiveData(backPressureStrategy: BackpressureStrategy) :  LiveData<T> {
    return LiveDataReactiveStreams.fromPublisher(this.toFlowable(backPressureStrategy))
}

fun <T> Single<T>.toLiveData() :  LiveData<T> {
    return LiveDataReactiveStreams.fromPublisher(this.toFlowable())
}

fun <T> Maybe<T>.toLiveData() :  LiveData<T> {
    return LiveDataReactiveStreams.fromPublisher(this.toFlowable())
}

fun <T> Completable.toLiveData() :  LiveData<T> {
    return LiveDataReactiveStreams.fromPublisher(this.toFlowable())
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 这是一个好主意吗?
  2. 有没有更好的方法呢?
  3. 这些扩展功能可以更好吗?

PS

我是Kotlin的新手,所以我问这些问题.任何有用的东西将不胜感激.非常感谢你.

android kotlin rx-java2 android-livedata android-architecture-components

18
推荐指数
2
解决办法
6192
查看次数

在 Kotlin 的 Stateflow 上使用映射

通过 Viewmodel 中的 LiveData,我们可以像这样使用 switchMap 或 Transformations.map

val recipesList = cuisineType.switchMap { repository.getDisplayRecipes(it.cuisineType).asLiveData() }
Run Code Online (Sandbox Code Playgroud)

使用 StateFlow 实现此目的的最佳方法是什么?我知道我们可以像下面一样使用地图,但是这会返回 Flow<Flow<List<Recipe>>> ,这似乎不正确

val recipeListFlow = cuisineTypeStateFlow.map {
    repository.getDisplayRecipes(it.cuisineType)
}
Run Code Online (Sandbox Code Playgroud)

android viewmodel kotlin android-livedata kotlin-stateflow

18
推荐指数
1
解决办法
1万
查看次数