小编Gun*_*ein的帖子

Android 中的 HashMap、SparseArray:多线程问题?

我知道 HashMap 和 SparseArray 都不是线程安全的。如果我有一个中央数据存储库作为 HashMap 可以被活动访问,并且可能被 AsyncTask 访问,我是否必须担心?

为了安全起见,建议使用 HashTable 或更好的 ConcurrentHashMap 吗?

multithreading android hashmap sparse-array concurrenthashmap

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

MVVM - 在应用程序关闭时从通知开始访问 BroadcastReceiver 中的 ViewModel/SQLite

我有每隔几天发送一次的提醒通知。

该通知的发送由重复触发AlarmManager。该通知本身是建立在onReceive我的BroadcastReceiver(如描述在这里)。所以当onReceive被触发时,应用程序甚至没有打开/运行。

现在我想访问我的(本地)SQLite 数据库并获得正确的内容来构建通知,但是我如何ViewModelProvider在这个地方获得一个(代码中的 xxx)来访问我的ViewModel?

public void onReceive(Context context, Intent intent) {    

    NotificationViewModel viewModel = 
    ViewModelProviders.of(XXX).get(NotificationViewModel.class);

    //do stuff
}
Run Code Online (Sandbox Code Playgroud)

或者问一个更好的问题,这甚至是好的做法吗?
另一种可能性是PendingIntent将触发 的所有内容填充到 中onReceive,因此我可以在收到后一一检索它。但这会更难,因为它是一个重复的警报,每次都需要不同的内容,但只触发一次。


我查看了一些搜索结果,但它们没有解决我的问题:

  • Android 上自定义视图的 MVVM 架构
    -> 对于这样一个小问题,似乎有很多代码,再加上是 Kotlin,这对我来说很难理解
  • 使用 Model View Presenter 设计模式处理 BroadcastReceivers
    -> 这里似乎有必要先在活动中设置一些东西,然后才能使用它,但我需要在没有运行我的应用程序的情况下启动此代码
  • 在 Viewmodel 中访问 BroadCastReceiver
    ->这似乎最接近我需要的,但它也需要之前的设置。我想试试这个,但我需要手动创建我的 MainActivity 来访问它的变量。这不会在没有警告的情况下在用户的设备上打开一个新活动吗?
    甚至可以在我的应用程序不在前台的情况下访问我的数据库吗?

编辑:

读取LiveData 超出 ViewModel [...],据说

如果您的应用程序的一部分不影响 UI,则您可能不需要 LiveData。

所以这意味着我应该简单地使用上下文访问我的存储库并从中获取原始数据, …

android mvvm broadcastreceiver viewmodel android-viewmodel

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

如何在房间 SQLite 数据库中自动设置时间戳?

我试图让 SQLite 使用 CURRENT_TIMESTAMP 创建自动时间戳。

我冒昧地使用了谷歌的代码

// roomVersion = '2.2.2'
@Entity
public class Playlist {
    @PrimaryKey(autoGenerate = true)
    long playlistId;
    String name;
    @Nullable
    String description;
    @ColumnInfo(defaultValue = "normal")
    String category;
    @ColumnInfo(defaultValue = "CURRENT_TIMESTAMP")
    String createdTime;
    @ColumnInfo(defaultValue = "CURRENT_TIMESTAMP")
    String lastModifiedTime;
}

@Dao
interface PlaylistDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(playlist: Playlist): Long
}
Run Code Online (Sandbox Code Playgroud)

这转化为 SQLite 语句:

CREATE TABLE `Playlist` (
    `playlistId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
    `name` TEXT, 
    `description` TEXT, 
    `category` TEXT DEFAULT 'normal', 
    `createdTime` TEXT …
Run Code Online (Sandbox Code Playgroud)

sqlite android-room

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

Android Studio:创建第二个Windows窗口

我熟悉Android Studio,现在比Eclipse更喜欢它.但是我发现Eclipse的窗口处理更加高效和灵活.

  1. 有没有办法为同一个项目打开第二个窗口(就像你有单独的项目一样)?基本上是Eclipse的"新窗口"功能.

  2. 有没有办法存储不同的窗口布局并在它们之间快速切换(如Eclipse的透视图)

我正在笔记本电脑上开发,因此空间有限.我宁愿在IDE窗口之间切换Alt+ 而Tab不是调整5个停靠窗口的大小.

android-studio

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

约束布局片段内容与底部导航重叠

我正在使用 Android Studio 3.6 来构建一个新项目“底部导航活动”。

activity_main.xml 中的片段容器具有约束: app:layout_constraintBottom_toTopOf="@id/nav_view"

我原以为片段的底部现在位于导航视图上方。

但是当我在 fragment_home.xml 中添加一个按钮时:

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="35dp"
    android:text="Button"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent" />
Run Code Online (Sandbox Code Playgroud)

按钮与导航栏重叠(已添加底部边距):

在此处输入图片说明

我的误会在哪里?如何使片段底部位于导航栏上方?

添加了 xml 布局:

活动_main.xml :

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu" />

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" // <-- solution: change to android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@id/nav_view"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/mobile_navigation" />

</androidx.constraintlayout.widget.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)

fragment_home.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.home.HomeFragment">

    <TextView
        android:id="@+id/text_home"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:textAlignment="center"
        android:textSize="20sp" …
Run Code Online (Sandbox Code Playgroud)

android android-constraintlayout

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