小编Boh*_*sen的帖子

Android架构组件:使用枚举

是否可以使用新的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)

android android-room android-architecture-components

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

Android Room Persistence Library:处理错误

我正在试图找出如何处理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)

android android-room

14
推荐指数
0
解决办法
1831
查看次数

Android Studio 4.1 Canary:Firebase Crashlytics 破坏了 android 项目编译

更新:这是在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 firebase crashlytics-android

11
推荐指数
1
解决办法
4612
查看次数

Android Room:带有嵌套 DAO 的 DAO

有没有办法使用 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)

android android-room

9
推荐指数
1
解决办法
962
查看次数

启动ActionMode时有两个动作栏

我有以下活动布局:

<?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)

android toolbar android-actionmode

8
推荐指数
2
解决办法
2047
查看次数

使用 Hilt 注入 CoroutineWorker

我正在尝试使用 dagger hilt 注入协同工作程序,我已按照文档中的所有说明进行操作

https://developer.android.com/training/dependency-injection/hilt-jetpack 用于“工人”而不是“协程工人”..

但它给出了一个错误:

java.lang.NoSuchMethodError: No interface method getBackgroundExecutor()Ljava/util/concurrent/Executor

..在stackoverflow上发布了同样的问题,但答案不适合我的情况

无法使用 Hilt 注入 workmanager 构造函数

这是代码和错误

如果有人可以提供帮助,我将不胜感激……这是我的代码

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)

android coroutine kotlin dagger-hilt

6
推荐指数
2
解决办法
1702
查看次数

将SpotBugs添加到我的项目

我一直在努力添加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)

android gradle spotbugs

5
推荐指数
1
解决办法
3788
查看次数

Android Motionlayout: Android resource linking failed

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 android-motionlayout

4
推荐指数
1
解决办法
585
查看次数

Kotlin 协程:在测试 Android Presenter 时切换上下文

我最近开始在我的 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 必须在两个地方维护。所以我的问题是。如何更改我的实现以支持简单的测试?

android unit-testing kotlin kotlinx.coroutines

3
推荐指数
1
解决办法
2394
查看次数

Kotlin:单元测试将函数作为参数的函数

我有一个从存储库中检索项目列表的函数.我没有使用常规回调,而是传入一个函数并使用结果调用它.但是你如何对这种功能进行单元测试呢?有没有办法验证传入的函数是否被调用,或者我应该重构和使用常规回调并使用模拟的回调接口测试它?

我的代码:

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)

android unit-testing kotlin

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

Android数据绑定和LiveData:无法绑定到LiveData属性中的值

我正在尝试对应该显示通过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

0
推荐指数
2
解决办法
1274
查看次数