小编dgl*_*ano的帖子

在新的Android推荐架构中,BoundService + LiveData + ViewModel最佳实践

我一直在努力思考将Android服务放在新的Android推荐架构中的位置.我提出了许多可能的解决方案,但我无法决定哪一个是最好的方法.

我做了很多研究,我找不到任何有用的指导方针或教程.我发现关于将服务放置在我的应用程序架构中的唯一提示是@JoseAlcerreca Medium post

理想情况下,ViewModels不应该对Android有任何了解.这提高了可测试性,泄漏安全性和模块化.一般的经验法则是确保ViewModel中没有android.*导入(例如android.arch.*).这同样适用于演示者.

根据这一点,我应该将我的Android服务置于我的架构组件层次结构的顶层,与我的活动和碎片处于同一级别.这是因为Android服务是Android框架的一部分,所以ViewModels不应该知道它们.

现在,我将简要介绍一下我的场景,但只是为了让全景更清晰,而不是因为我想要这个特定场景的答案.

  • 我有一个Android应用程序,其中包含MainActivity,其中包含许多片段,所有这些片段都绑定在BottomNavBar中.
  • 我有一个绑定到myActivity的蓝牙服务及其中一个片段(因为我希望服务与Activty具有相同的生命周期,但我也希望直接从我的片段与它进行交互).
  • 该片段与BluetoothService交互以获取两种类型的信息:
    • 有关蓝牙连接状态的信息.不需要坚持.
    • 来自蓝牙设备的数据(在这种情况下,它是比例,因此重量和身体构成).需要坚持下去.

以下是我能想到的3种不同架构:

AndroidService中的LiveData Android服务范围内的LiveData

  • 具有连接状态和来自蓝牙设备的重量测量值的LiveData位于BluetoothService内.
  • Fragment可以触发BluetoothService中的操作(例如scanDevices)
  • Fragment观察LiveData有关连接的状态并相应地调整UI(例如,如果状态已连接,则启用按钮).
  • Fragment观察新重量测量的LiveData.如果新的权重测量来自BluetoothDevice,则Fragment会告诉自己的ViewModel保存新数据.它通过Repository类完成.

片段和AndroidService之间共享ViewModel 共享ViewModel arch

  • Fragment可以触发BluetoothService中的操作(例如scanDevices)
  • BluetoothService更新共享ViewModel中的蓝牙相关LiveData.
  • Fragment在自己的ViewModel中观察LiveData.

服务ViewModel 服务ViewMOdel拱门

  • Fragment可以触发BluetoothService中的操作(例如scanDevices)
  • BluetoothService在其自己的ViewModel中更新蓝牙相关的LiveData.
  • Fragment在自己的ViewModel和BluetoothService ViewModel中观察LiveData.

我很确定我应该将它们放在架构之上并将它们视为一个Activity/Fragment,因为BoundServices是Android Framework的一部分,它们由Android操作系统管理,并且它们与其他活动和片段绑定.在这种情况下,我不知道与LiveData,ViewModels和Activities/Fragments交互的最佳方式是什么.

有些人可能认为它们应该被视为一个数据源(因为在我的情况下,它使用蓝牙从一个规模获取数据),但我不认为这是一个好主意,因为我在上一段中所说的都是特别是因为它在这里所说的:

避免将应用的入口点(如活动, 服务和广播接收器)指定为数据源.相反,它们应该只与其他组件协调以检索与该入口点相关的数据子集.每个应用程序组件都是相当短暂的,具体取决于用户与其设备的交互以及系统的整体当前运行状况.

所以,最后,我的问题是:

我们应该在哪里放置我们的Android(绑定)服务以及它们与其他架构组件的关系?这些替代品中的任何一种都是好方法吗?

android android-service android-architecture android-architecture-components android-jetpack

28
推荐指数
1
解决办法
3284
查看次数

EF Core 属性值转换在派生实体配置中不起作用

我有一个通用 EF BaseEntityConfiguration 类,用于设置基本属性(如主键、用于软删除的属性、查询过滤器等)以及存储 System.Type 和 JSON 属性的实体的派生配置。如果我不使用泛型类而仅实现 IEntityTypeConfiguration,则值转换将起作用并且不会出现错误。但是,如果我从基类继承,则会遇到有关在不进行任何转换的情况下保存类型和对象的 EF Core 问题。从基类继承并且不需要转换的其他配置可以正常工作。

错误:

Error: The property 'MessageLog.Data' could not be mapped because it is of type 'object', which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

public class MessageLogConfiguration
        //: IEntityTypeConfiguration<MessageLog>
        : BaseEntityConfiguration<MessageLog, int>
    {
        public MessageLogConfiguration(ILogger<MessageLogConfiguration> logger)
           : base(logger)
        { }

        public override void Configure(EntityTypeBuilder<MessageLog> builder)
        {
            base.Configure(builder); …
Run Code Online (Sandbox Code Playgroud)

.net c# entity-framework entity-framework-core asp.net-core

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

在 Entity Framework Core 上添加迁移时出现 NET 5 错误

我正在使用 Entity Framework Core 5 和 Postgres 设置一个新项目。我的所有项目和我的上下文都在同一个项目中。

\n

添加迁移时,我收到此错误:

\n
\n

/src/Api.csproj :错误 MSB4057:项目中不存在目标“GetEFProjectMetadata”。无法检索项目元数据。确保它是基于 MSBuild 的 .NET Core 项目。如果您使用自定义 BaseIntermediateOutputPath 或 MSBuildProjectExtensionsPath 值,请使用 --msbuildprojectextensionspath 选项。

\n
\n

EF Core 版本: 5.0.1\n目标框架: net5.0

\n

这些是我尝试过的所有命令:

\n
dotnet ef migrations add NewMigration\n\ndotnet ef migrations add NewMigration --msbuildprojectextensionspath     \n\ndotnet ef migrations add NewMigration -p ".\\src\\Api.csproj"\n\ndotnet ef migrations add NewMigration -p ".\\src\\Api.csproj" --msbuildprojectextensionspath*     \n
Run Code Online (Sandbox Code Playgroud)\n

我尝试了在互联网上找到的很多选项,但没有一个有效。

\n

如果我添加 -v ,最后几行是:

\n
Using project \'/media/pablo/l/Projetos/Web/backend/boilerplate/dotnet_csharp/src/Api.csproj\'.\nUsing startup project \'/media/pablo/l/Projetos/Web/backend/boilerplate/dotnet_csharp/src/Api.csproj\'.\nWriting \'/media/pablo/l/Projetos/Web/backend/boilerplate/dotnet_csharp/src/obj/Api.csproj.EntityFrameworkCore.targets\'...\ndotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=/tmp/tmpbscOwZ.tmp /verbosity:quiet /nologo …
Run Code Online (Sandbox Code Playgroud)

.net c# entity-framework docker entity-framework-core

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

Android BLE 扫描永远找不到设备

几天以来,我尝试在我的应用程序中实现 BLE 连接。我知道我尝试连接的设备功能齐全,因此问题一定是我的代码。

我用的是BluetoothLeScanner.startScan()方法。
但回调方法永远不会被调用。

   public void startScan() {
        if (bluetoothAdapter != null && bluetoothAdapter.isEnabled()) {
            isScanning = true;
            Handler mHandler = new Handler();
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mainActivityHandler.setMSG("Scan stopped");
                    isScanning = false;
                    leScanner.stopScan(scanCallback);
                }
            }, SCAN_TIME);

            mainActivityHandler.setMSG("Start scan");

            try {

                leScanner.startScan(scanCallback);
            } catch (Exception e) {
                mainActivityHandler.catchError(e);
            }

        } else mainActivityHandler.catchError(new Exception("Bluetooth not activated"));
    }
Run Code Online (Sandbox Code Playgroud)

我的 CallbackMethod (不知道我是否正确使用 gatt,但这是另一个问题):

    private ScanCallback scanCallback = new ScanCallback() {


    @Override
    public void onBatchScanResults(List<ScanResult> results) {
        mainActivityHandler.setMSG("Callback"); …
Run Code Online (Sandbox Code Playgroud)

android bluetooth-lowenergy android-ble

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