标签: android-architecture-components

是否可以强制实施LiveData值的非空性?

有没有办法强制实现LiveData值的不可空性?默认的Observer实现似乎有@Nullable注释,它强制IDE建议该值可能为null并且应该手动检查:

public interface Observer<T> {
    /**
     * Called when the data is changed.
     * @param t  The new data
     */
    void onChanged(@Nullable T t);
}
Run Code Online (Sandbox Code Playgroud)

android android-livedata android-architecture-components

10
推荐指数
4
解决办法
3917
查看次数

没有Room的NetworkBoundResource助手类

当我尝试为Room Db和Retrofit 实现NetworkBoundResourceResource帮助类时,它完美无缺.但是,我需要在没有Room的情况下使用Retrofit实现RESTful的搜索结果.这Resources堂课很好,我不需要改变它.我想要做的是尝试删除此类中的数据库源.

public abstract class NetworkBoundResource<ResultType, RequestType> {
  private final AppExecutors appExecutors;

  private final MediatorLiveData<Resource<ResultType>> result = new MediatorLiveData<>();

  @MainThread
  public NetworkBoundResource(AppExecutors appExecutors) {
    this.appExecutors = appExecutors;
    result.setValue(Resource.loading(null));
    LiveData<ResultType> dbSource = loadFromDb();
    result.addSource(dbSource, data -> {
      result.removeSource(dbSource);
      if (shouldFetch(data)) {
        fetchFromNetwork(dbSource);
      } else {
        result.addSource(dbSource, newData -> setValue(Resource.success(newData)));
      }
    });
  }

  @MainThread
  private void setValue(Resource<ResultType> newValue) {
    if (!Objects.equals(result.getValue(), newValue)) {
      result.setValue(newValue);
    }
  }

  private void fetchFromNetwork(final LiveData<ResultType> dbSource) …
Run Code Online (Sandbox Code Playgroud)

android android-livedata android-architecture-components

10
推荐指数
2
解决办法
2699
查看次数

在AndroidViewModel中初始化LiveData

我正在寻找一种方法来初始化ViewModel中的LiveData对象.当前只有在从活动调用setQuery方法时才会初始化项目.

public class MyListViewModel extends AndroidViewModel {

private final LiveData <List<Item>> items;
private final MutableLiveData<String> query = new MutableLiveData<>();


private MyDatabase db;

public MyListViewModel(Application application) {
    super(application);
    db  = MyDatabase.getInstance(application);
    items = Transformations.switchMap(query, (search)->{
        if (search == null || search.trim().length() == 0) {
            return db.itemDao().getAllItems();
        } else {
            return db.itemDao().findItemsBySearchTerm(search);
        }
    });

}

public LiveData<List<Item>> getItems() {
    return items;
}

public void setQuery(String queryText) {
   query.setValue(queryText);
}
Run Code Online (Sandbox Code Playgroud)

}

android android-livedata android-architecture-components

10
推荐指数
1
解决办法
5784
查看次数

我们什么时候应该使用android.arch.lifecycle:compiler(或android.arch.lifecycle:common-java8)?

目前,我们正在使用LiveDataViewModelRoom在我们的项目。

我们正在使用Java 8。

我们在下面使用 build.gradle

// ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:1.1.1"

// Room (use 1.1.0-beta1 for latest beta)
implementation "android.arch.persistence.room:runtime:1.0.0"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"
Run Code Online (Sandbox Code Playgroud)

我想知道我们什么时候需要使用

annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
Run Code Online (Sandbox Code Playgroud)

(或者implementation "android.arch.lifecycle:common-java8:1.1.1"因为我们正在使用Java 8 ?!)

目前,我们的代码可以正常运行,而无需使用lifecycle:compilerlifecycle:common-java8

android android-architecture-components

10
推荐指数
4
解决办法
4627
查看次数

如何从Android Room中的多个数据库中选择(如何附加数据库)

如您所知,我们可以使用attach命令从多个数据库中选择,如下所示:

String path = DBHelper.getDatabasePath(context);
String sql = "ATTACH DATABASE '" + path + "/" + dbname.toString()
                + ".db' AS \"" + dbname.toString() + "\";";
db.execSQL(sql);
Run Code Online (Sandbox Code Playgroud)

然后通过使用Cursor,我们可以从中进行选择.

通过使用Android Room,我该怎么做?是否有任何附件或类似命令来执行此操作?

java sqlite android android-room android-architecture-components

10
推荐指数
2
解决办法
3006
查看次数

如何一个接一个地组合两个实时数据?

我有下一个用例:用户登录表格,输入姓名,电子邮件和密码,点击注册按钮.之后系统需要检查电子邮件是否被采用并基于该显示错误消息或创建新用户...

我试图使用Room,ViewModel和LiveData来做到这一点.这是我尝试学习这些组件的一些项目,我没有远程api,我会将所有内容存储在本地数据库中

所以我有这些课程:

  • RegisterActivity
  • RegisterViewModel
  • 用户
  • UsersDAO
  • UsersRepository
  • UsersRegistrationService

所以我的想法是将有一个监听器附加到注册按钮,它将调用RegisterViewModel::register()方法.

class RegisterViewModel extends ViewModel {

    //...

    public void register() {
        validationErrorMessage.setValue(null);
        if(!validateInput())
            return;
        registrationService.performRegistration(name.get(), email.get(), password.get());
    }

    //...

}
Run Code Online (Sandbox Code Playgroud)

所以这是基本的想法,我也想performRegistration回到我新建的用户.

最困扰我的是我不知道如何performRegistration在服务中实现功能

class UsersRegistrationService {
    private UsersRepository usersRepo;

    //...

    public LiveData<RegistrationResponse<Parent>>  performRegistration(String name, String email, String password) {
         // 1. check if email exists using repository
         // 2. if user exists return RegistrationResponse.error("Email is taken") 
         // 3. if user does not exists create new user …
Run Code Online (Sandbox Code Playgroud)

android observer-pattern android-room android-livedata android-architecture-components

10
推荐指数
7
解决办法
6477
查看次数

如何在使用导航组件时设置对话框的目标片段

我在一个片段里面使用childFragmentManager或在一个Activity 里面显示一个对话框supportFragmentManager,在这个过程中我想设置目标片段,如下所示:

val textSearchDialog = TextSearchDialogFragment.newInstance()
textSearchDialog.setTargetFragment(PlaceSearchFragment@this, 0)
Run Code Online (Sandbox Code Playgroud)

但是当运行该代码时,我得到错误:

java.lang.IllegalStateException:Fragment TextSearchDialogFragment {b7fce67#0 0}声明的目标片段PlaceSearchFragment {f87414#0 id = 0x7f080078}不属于此FragmentManager!

我不知道如何访问FragmentManager导航组件正在使用来管理片段的显示,有没有解决方案呢?

android kotlin android-navigation android-architecture-components android-architecture-navigation

10
推荐指数
2
解决办法
2405
查看次数

从Android Room Architecture Component中的多对多结构中获取LiveData

我们来看一个基本的例子

用于存储用户的表

@Entity (tableName="users") 
class UsersEntity(
     @PrimaryKey val id
     var name:String,
      ...
) 
Run Code Online (Sandbox Code Playgroud)

用于存储角色的表

@Entity (tableName="roles") 
class RolesEntity(
     @PrimaryKey val id
     var name:String,
      ...
) 
Run Code Online (Sandbox Code Playgroud)

用于存储用户和角色之间的多对多关系的表

@Entity (tableName="roles") 
class UserRoles(
     @PrimaryKey val id
     var userId:String,
     var roleId:String
) 
Run Code Online (Sandbox Code Playgroud)

我在视图中需要的pojo类

class user(
    var id:String,
    var name:String,
     .... other fields
     var roles: List<Role>
)
Run Code Online (Sandbox Code Playgroud)

在我,我ViewModel怎么能把user结果传递给LiveData已经List<Role>填满?

从一般方面来看,我可以:

  • UserDao.getUserById(id)返回LiveData从用户表,并RoleDao.getRolesForUserId(id)返回LiveData与用户的角色列表.然后在我的片段,我所能做的viewModel.getUserById().observe{}viewModel.getRolesForUserId().observe{}.但这基本上意味着拥有2名观察员,而且我非常有信心这不是可行的方法.
  • 可能其他方式是能够以某种方式在我的存储库或viewmodel中混合它们,以便它返回我需要的东西.我会调查一下MediatorLiveData

android-room android-livedata android-viewmodel android-architecture-components android-jetpack

10
推荐指数
1
解决办法
914
查看次数

为什么LiveData仍然通知处于onPause状态的Activity?

我有以下代码 Activity

@Override
public void onPause() {
    super.onPause();

    if (isFinishing()) {
        final LiveData<StickyNoteConfig> stickyNoteConfigLiveData = StickyNoteConfigRepository.INSTANCE.getStickyNoteConfig(mAppWidgetId);
        stickyNoteConfigLiveData.removeObservers(this);
        stickyNoteConfigLiveData.observe(this, stickyNoteConfig -> {
            // Weird, I still can receive call back.
            // I thought "this" is no longer active?
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我感到困惑的Observer是,虽然this活动已经处于onPause状态,但仍然被触发了?根据https://developer.android.com/reference/android/arch/lifecycle/Lifecycle.State#STARTED

为LifecycleOwner启动状态.对于活动,在两种情况下达到此状态:

after onStart call;
right before onPause call.
Run Code Online (Sandbox Code Playgroud)

我可以知道为什么会这样吗?

android android-livedata android-architecture-components

10
推荐指数
1
解决办法
1679
查看次数

Room Dao LiveData作为返回类型导致编译时间错误

我正在使用Room并实现了Dao,它返回了LiveData。添加下面的依赖关系,它工作正常。

implementation "androidx.room:room-runtime:2.1.0-alpha04"
kapt "androidx.room:room-compiler:2.1.0-alpha04"
Run Code Online (Sandbox Code Playgroud)

但是,当我添加新的Room协程依赖性时,如下所述。

implementation "androidx.room:room-runtime:2.1.0-alpha04"
implementation "androidx.room:room-coroutines:2.1.0-alpha04"
kapt "androidx.room:room-compiler:2.1.0-alpha04"
Run Code Online (Sandbox Code Playgroud)

下面是编译的代码

@Dao
interface AccountDao{

    @Query("SELECT * FROM account_master")
    suspend fun getAllAccounts(): List<Account>
}
Run Code Online (Sandbox Code Playgroud)

下面是给出错误的代码。

@Dao
interface AccountDao{

    @Query("SELECT * FROM account_master")
    suspend fun getAllAccounts(): LiveData<List<Account>>
}
Run Code Online (Sandbox Code Playgroud)

开始收到错误。

PlayGround/app/build/tmp/kapt3/stubs/debug/com/playground/www/x/datasource/dao/AccountDao.java:11: error: Not sure how to convert a Cursor to this method's return type (androidx.lifecycle.LiveData<java.util.List<com.playground.www.x.datasource.entity.Account>>).
public abstract java.lang.Object getAllAccounts(@org.jetbrains.annotations.NotNull()
Run Code Online (Sandbox Code Playgroud)

有人面临类似问题吗?

android android-room android-architecture-components kotlin-coroutines

10
推荐指数
3
解决办法
2237
查看次数