是否可以使用新的Android架构组件和房间持久性库将Enum类型用作Entity类中的嵌入字段?
我的实体(带有嵌入式枚举):
@Entity(tableName = "tasks")
public class Task extends SyncEntity {
@PrimaryKey(autoGenerate = true)
String taskId;
String title;
/** Status of the given task.
* Enumerated Values: 0 (Active), 1 (Inactive), 2 (Completed)
*/
@Embedded
Status status;
@TypeConverters(DateConverter.class)
Date startDate;
@TypeConverters(StatusConverter.class)
public enum Status {
ACTIVE(0),
INACTIVE(1),
COMPLETED(2);
private int code;
Status(int code) {
this.code = code;
}
public int getCode() {
return code;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的TypeConverter:
public class StatusConverter {
@TypeConverter
public static Task.Status toStatus(int status) {
if …Run Code Online (Sandbox Code Playgroud) 我正在试图找出如何处理Room的错误.我有以下在数据库中插入任务的交互器:
TaskInteractor.java
public class TaskInteractor extends AbstractInteractor implements TaskContract.Interactor {
final TaskRepository mRepository;
interface Callback {
void onSuccess();
void onFailure(Throwable t);
}
@Inject
public TaskInteractor(WorkerThread workerThread,
MainThread mainThread,
TaskRepository repository) {
super(workerThread, mainThread);
this.mRepository = repository;
}
@Override
public void insertTask(final Task task, final Callback callback)
throws SQLiteException {
mWorkerThread.get().execute(new Runnable() {
@Override
public void run() {
try {
mRepository.insertTask(task);
} catch (SQLiteException exeption) {
Timber.e("Insertion failed. Exception: " + exeption.getMessage());
callback.onFailure(exeption);
throw exeption;
}
Timber.d("Insertion succeeded.");
callback.onSuccess();
}
}); …Run Code Online (Sandbox Code Playgroud) 更新:这是在Crashlytics Gradle 插件版本 2.0.0-beta04 中修复的。
一直试图从我正在处理的项目中删除即将弃用的 Fabric Crashlytics SDK,以支持新的 Firebase Crashlytics SDK。不幸的是,我在编译之后遇到了麻烦。我不断收到以下异常:
Gradle sync failed: No such property: scope for class: com.android.build.gradle.internal.variant.ApplicationVariantData
这是堆栈跟踪:
Caused by: groovy.lang.MissingPropertyException: No such property: scope for class: com.android.build.gradle.internal.variant.ApplicationVariantData
at com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsPlugin.configureTaskDependencies(CrashlyticsPlugin.groovy:199)
at com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsPlugin.configureUploadTask(CrashlyticsPlugin.groovy:187)
at com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsPlugin.registerMappingFileTasks(CrashlyticsPlugin.groovy:142)
at com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsPlugin$registerMappingFileTasks.callCurrent(Unknown Source)
at com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsPlugin.registerCrashlyticsTasks(CrashlyticsPlugin.groovy:101)
at org.gradle.internal.metaobject.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:483)
at org.gradle.internal.metaobject.BeanDynamicObject.tryInvokeMethod(BeanDynamicObject.java:195)
at org.gradle.internal.metaobject.ConfigureDelegate.invokeMethod(ConfigureDelegate.java:77)
at com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsPlugin$_apply_closure3.doCall(CrashlyticsPlugin.groovy:71)
at org.gradle.util.ClosureBackedAction.execute(ClosureBackedAction.java:71)
at org.gradle.util.ConfigureUtil.configureTarget(ConfigureUtil.java:154)
at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:105)
at org.gradle.util.ConfigureUtil$WrappedConfigureAction.execute(ConfigureUtil.java:166)
at org.gradle.api.internal.DefaultCollectionCallbackActionDecorator$BuildOperationEmittingAction$1$1.run(DefaultCollectionCallbackActionDecorator.java:100)
at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.reapply(DefaultUserCodeApplicationContext.java:60)
at org.gradle.api.internal.DefaultCollectionCallbackActionDecorator$BuildOperationEmittingAction$1.run(DefaultCollectionCallbackActionDecorator.java:97)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
at …Run Code Online (Sandbox Code Playgroud) 有没有办法使用 Android Room Persistence Library 将 DAO 添加为其他 DAO 中的依赖项,也许是使用 Dagger2?我试图避免使用事务对多个表进行操作的 DAO 类中的方法爆炸。
这就是我正在努力实现的目标。
示例:FooBarRepository.class
@Dao
public abstract class FooBarRepository {
// THESE ARE DAOs ADDED AS DEPENDENCIES
FooRepository fooRepository;
BarRepository barRepository;
...
@Transaction
public void insertOrUpdateInTransaction(FooBar... foobars) {
for (FooBar item : foobars) {
fooRepository.insertOrUpdateInTransaction(item.getFoo());
barRepository.insertOrUpdateInTransaction(item.getBar());
}
}
}
Run Code Online (Sandbox Code Playgroud) 我有以下活动布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawerLayout"
style="@style/DrawerLayout"
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">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".ui.activity.MyActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/app_bar_height"
android:background="@color/black"
android:fitsSystemWindows="true"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:collapsedTitleTextAppearance="@style/ToolbarTitle"
app:contentScrim="@color/primary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_top"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:theme="@style/ThemeOverlay.AppCompat.Light"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<my.package.ui.widget.MyHeaderWidget
android:id="@+id/deal_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="my.package.ui.activity.MyHeaderBehavior"/>
<include layout="@layout/content_list"/>
</android.support.design.widget.CoordinatorLayout>
<include layout="@layout/navigation_view"/>
</android.support.v4.widget.DrawerLayout>
Run Code Online (Sandbox Code Playgroud)
它用于具有折叠工具栏+导航抽屉+标题动画和子标题(在标题小部件中).在我尝试启动ActionMode以启用多选之前,一切都很好.
我通过致电来做到:
mActionMode = mCollapsingToolbarLayout.startActionMode(mActionModeCallback);
Run Code Online (Sandbox Code Playgroud)
问题是我结束了两个动作栏(有两个箭头):
黑色的那个是我期待在那里的那个,当我启动ActionMode时添加了白色的那个.
难道我做错了什么?
编辑
在AndroidMaifest中
<activity
android:name=".ui.activity.MyActivity"
android:label="@string/title_activity"
android:theme="@style/MyTheme">
</activity>
Run Code Online (Sandbox Code Playgroud)
在styles.xml中
<style name="MyTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowBackground">@drawable/window_background_gray</item>
<item name="android:colorBackground">@color/app_background</item>
<item name="displayOptions">showHome|homeAsUp|showTitle</item>
<item name="android:icon">@android:color/transparent</item>
<item …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 dagger hilt 注入协同工作程序,我已按照文档中的所有说明进行操作
https://developer.android.com/training/dependency-injection/hilt-jetpack 用于“工人”而不是“协程工人”..
但它给出了一个错误:
java.lang.NoSuchMethodError: No interface method getBackgroundExecutor()Ljava/util/concurrent/Executor
..在stackoverflow上发布了同样的问题,但答案不适合我的情况
这是代码和错误
如果有人可以提供帮助,我将不胜感激……这是我的代码
package com.example.moviemania.work
import android.content.Context
import androidx.hilt.Assisted
import androidx.hilt.work.WorkerInject
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.example.moviemania.repository.MainRepository
import retrofit2.HttpException
class RefreshDataWorker @WorkerInject constructor (
@Assisted appContext: Context,
@Assisted params: WorkerParameters,
val mainRepository: MainRepository
) : CoroutineWorker(appContext,params) {
companion object {
const val WORK_NAME = "com.example.moviemania.work.RefreshDataWorker"
}
override suspend fun doWork(): Result {
try {
mainRepository.refreshMovies()
}catch (e: HttpException){
return Result.retry()
}
return Result.success() …Run Code Online (Sandbox Code Playgroud) 我一直在努力添加SpotBugs到当前正在处理的android项目中。我设法使其正常运行,但是我对它的设置方式并不感到太兴奋。现在,配置位于我的app / build.gradle文件中,这使文件的管理更简单。
我想知道是否有SpotBugs / Gradle的专家,他知道一种将配置提取到单独文件中的方法。
这是我的app / build.gradle(样板已删除):
buildscript {
repositories {
...
}
dependencies {
classpath 'com.stanfy.spoon:spoon-gradle-plugin:1.2.2'
classpath 'io.fabric.tools:gradle:1.25.4'
classpath "org.jetbrains.dokka:dokka-android-gradle-plugin:$dokka_version"
}
}
plugins {
id 'com.gladed.androidgitversion' version '0.4.3'
id "com.github.spotbugs" version "1.6.2"
}
...
apply plugin: 'com.github.spotbugs'
apply from: '../config/quality/quality.gradle'
apply from: '../app/jacoco.gradle'
apply from: '../app/ktlint.gradle'
apply from: '../app/androidgit.gradle'
...
spotbugs {
toolVersion = '3.1.3'
ignoreFailures = false
effort = "min"
// This selects what level of bugs to report: low means low priority issues …Run Code Online (Sandbox Code Playgroud) I keep getting build errors after a refactor to motionlayout 2.0.0-beta1 (I know it's not the newest version - beta2 produces same errors).
Here's the stacktrace:
AAPT: /Users/TBS/StudioProjects/ExampleApp/app/build/intermediates/incremental/mergeDebugResources/merged.dir/values/values.xml:6514: error: resource attr/flow_horizontalSeparator (aka com.example:attr/flow_horizontalSeparator) not found.
/Users/TBS/StudioProjects/ExampleApp/app/build/intermediates/incremental/mergeDebugResources/merged.dir/values/values.xml:6514: error: resource attr/flow_verticalSeparator (aka com.example:attr/flow_verticalSeparator) not found.
/Users/TBS/StudioProjects/ExampleApp/app/build/intermediates/incremental/mergeDebugResources/merged.dir/values/values.xml:6515: error: resource attr/flow_horizontalSeparator (aka com.example:attr/flow_horizontalSeparator) not found.
/Users/TBS/StudioProjects/ExampleApp/app/build/intermediates/incremental/mergeDebugResources/merged.dir/values/values.xml:6515: error: resource attr/flow_verticalSeparator (aka com.example:attr/flow_verticalSeparator) not found.
/Users/TBS/StudioProjects/ExampleApp/app/build/intermediates/incremental/mergeDebugResources/merged.dir/values/values.xml:6517: error: resource attr/flow_horizontalSeparator (aka com.example:attr/flow_horizontalSeparator) not found.
/Users/TBS/StudioProjects/ExampleApp/app/build/intermediates/incremental/mergeDebugResources/merged.dir/values/values.xml:6517: error: resource attr/flow_verticalSeparator (aka com.example:attr/flow_verticalSeparator) not found.
/Users/TBS/StudioProjects/ExampleApp/app/build/intermediates/incremental/mergeDebugResources/merged.dir/values/values.xml:6517: error: resource attr/motionProgress (aka …Run Code Online (Sandbox Code Playgroud) 我最近开始在我的 Android 项目中使用 kotlin 协程,但我遇到了一些问题。许多人将其称为代码异味。
我正在使用 MVP 架构,其中协程在我的演示者中启动,如下所示:
// WorklistPresenter.kt
...
override fun loadWorklist() {
...
launchAsync { mViewModel.getWorklist() }
...
Run Code Online (Sandbox Code Playgroud)
该launchAsync函数以这种方式实现(在我的 WorklistPresenter 类扩展的 BasePresenter 类中):
@Synchronized
protected fun launchAsync(block: suspend CoroutineScope.() -> Unit): Job {
return launch(UI) { block() }
}
Run Code Online (Sandbox Code Playgroud)
问题在于我使用的是依赖于 Android 框架的 UI 协程上下文。我无法将其更改为另一个协程上下文而不会遇到ViewRootImpl$CalledFromWrongThreadException. 为了能够对此进行单元测试,我创建了一个 BasePresenter 的副本,其中包含不同的实现launchAsync:
protected fun launchAsync(block: suspend CoroutineScope.() -> Unit): Job {
runBlocking { block() }
return mock<Job>()
}
Run Code Online (Sandbox Code Playgroud)
对我来说这是一个问题,因为现在我的 BasePresenter 必须在两个地方维护。所以我的问题是。如何更改我的实现以支持简单的测试?
我有一个从存储库中检索项目列表的函数.我没有使用常规回调,而是传入一个函数并使用结果调用它.但是你如何对这种功能进行单元测试呢?有没有办法验证传入的函数是否被调用,或者我应该重构和使用常规回调并使用模拟的回调接口测试它?
我的代码:
class WorklistInteractor @Inject
constructor(private val worklistRepository: WorklistRepository,
private val preferenceManager: PreferenceManager,
private val executor: Executor)
: WorklistDialogContract.Interactor, Executor by executor {
@Volatile private var job: Job? = null
override fun getWorklist(callback: (Result<List<WorklistItem>>) -> Unit) {
job = onWorkerThread {
val result = worklistRepository.getWorklist().awaitResult()
onMainThread { callback(result) }
}
}
override fun cancel() {
job?.cancel()
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试对应该显示通过ViewModel中的LiveData属性公开的数据的视图进行数据绑定,但是我没有找到将LiveData中的对象绑定到视图的方法。从XML中,我只能访问LiveData实例的value属性,而不能访问其中的对象。我错过了什么吗?
我的ViewModel:
class TaskViewModel @Inject
internal constructor(private val taskInteractor: taskInteractor)
: ViewModel(), TaskContract.ViewModel {
override val selected = MutableLiveData<Task>()
val task: LiveData<Task> = Transformations.switchMap(
selected
) { item ->
taskInteractor
.getTaskLiveData(item.task.UID)
}
... left out for breivety ...
}
Run Code Online (Sandbox Code Playgroud)
我试图将任务对象的值绑定到我的视图中,但是当尝试在我的视图中设置任务的值时,我只能这样做android:text="@={viewmodel.task.value}"。我无权访问任务对象的字段。在LiveData对象中提取对象值的诀窍是什么?
我的任务课:
@Entity(tableName = "tasks")
data class Task(val id: String,
val title: String,
val description: String?,
created: Date,
updated: Date,
assigned: String?)
Run Code Online (Sandbox Code Playgroud) android android-databinding android-livedata android-viewmodel
android ×11
android-room ×3
kotlin ×3
unit-testing ×2
android-architecture-components ×1
coroutine ×1
dagger-hilt ×1
firebase ×1
gradle ×1
spotbugs ×1
toolbar ×1