我正在遵循MVVM使用Android Architecture Components和Data Binding库的架构。
TL; 博士
ViewModel在复合视图中引用对象是否违反了 MVVM 架构?我查看了 Google 的示例,只看到它在 Activity/Fragment XML 中使用,但没有在自定义视图中使用。
有问题的代码
我有一个复合视图,我想在许多地方重复使用它。它从 XML 实例化。该视图根据用户输入进行填充。我想确保用户输入的任何内容都能在方向更改中幸存下来。请考虑我匆忙编写的以下代码来说明场景:
public class RestaurantActivity extends AppCompatActivity {
RestaurantViewModel viewModel;
RestaurantActivityBinding binding;
@Override
public void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
binding = DataBindingUtil.setContentView(this, R.layout.restaurant_activity );
viewModel = ViewModelProviders.of( this ).get( RestaurantViewModel.class );
//is this "legal" for MVVM
binding.selectionView.setRestaurantViewModel( viewModel );
viewModel.extraHotSause.observe ( this, new Observer() {
@Override
void onChange(Boolean extraHotSauce ) {
binding.selectionView.extraHotSauce( extraHotSauce …Run Code Online (Sandbox Code Playgroud) android mvvm android-viewmodel android-architecture-components
ViewModel.OnCleared()当应用程序进入后台时(即使Don't keep activities已启用),当我没有被调用时,我偶然发现了一个问题,但我可以看到Fragment.onDestroy()实际上正在调用它.
以下代码可能有什么问题?如何ViewModel.OnCleared()在这种情况下实际调用?
视图模型:
class ViewModelFirst(application: Application) : AndroidViewModel(application) {
companion object {
private const val TAG = "ViewModelFirst"
}
init {
Log.v(TAG, "Created")
}
override fun onCleared() {
super.onCleared()
Log.v(TAG, "onCleared")
}
}
Run Code Online (Sandbox Code Playgroud)
分段:
class FragmentFirst : Fragment() {
companion object {
private const val TAG = "FragmentFirst"
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
ViewModelProviders.of(this).get(ViewModelFirst::class.java)
return inflater.inflate(R.layout.fragment_first, container, false)
}
override fun onDestroy() {
super.onDestroy()
Log.v(TAG, …Run Code Online (Sandbox Code Playgroud) 我正在将 Android 的导航架构组件集成到我的应用程序中。我在将数据从活动传递到片段的开头时遇到了一些问题,所以我遵循了这个答案:导航架构组件-将参数数据传递到 startDestination。
这个逻辑对我来说似乎很合理,但我正在努力确定如何实际获得 NavHostFragment。Elliot Shrock 使用了这条线——
val navHostFragment = navFragment as NavHostFragment
但我还没有找到一个有效的 Java 等价物。我尝试通过使用获取我的 navHost 的片段
getSupportFragmentManager().findFragmentById(R.id.[mynavhostid])
但此命令返回空值。有任何想法吗?
android android-fragments fragmentmanager android-architecture-components android-architecture-navigation
我们正在使用OneTimeWorkRequest在我们的项目中启动后台任务.
在某些情况下,如果应用程序在工作请求A正在进行时被杀死,Android会在应用程序重新启动时自动重新启动请求A. 我们再次再次启动请求A. 因此,请求A的两个实例并行运行并导致死锁.
为了避免这种情况,我在app start中执行了以下代码来检查worker是否正在运行但是这总是返回false.
public static boolean isMyWorkerRunning(String tag) {
List<WorkStatus> status = WorkManager.getInstance().getStatusesByTag(tag).getValue();
return status != null;
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来处理这个?
我检查了beginUniqueWork().如果我只有一个请求,是否更昂贵?
编辑2: 这个问题是关于独特的一次性任务.为了启动唯一的Periodic任务,我们有一个单独的API enqueueUniquePeriodicWork().但是我们没有用于启动独特的一次性工作的API.我很困惑在继续对象之间使用或手动检查和启动方法.
在最近的构建中,他们为这个enqueueUniqueWork()添加了新的api.这是他们在发行说明中提到的确切原因.
添加WorkManager.enqueueUniqueWork()API以将唯一的OneTimeWorkRequests排入队列,而无需创建WorkContinuation. https://developer.android.com/jetpack/docs/release-notes
android android-architecture-components android-jetpack android-workmanager
我一直在使用这里observeForever()描述的方法来测试Room和LiveData一段时间,并且它运行得很完美.但当我改为Android Studio 3.2(或者如果它是重构,不确定)时,该方法突然停止工作,抛出一个androidx
java.lang.IllegalStateException: Cannot invoke observeForever on a background thread
Run Code Online (Sandbox Code Playgroud)
我们该如何解决这个问题?
android android-room android-livedata android-architecture-components androidx
该文件 https://developer.android.com/topic/libraries/architecture/viewmodel#sharing描述了如何在不同的片段之间共享相同的ViewModel。
我的页面有些复杂 单个“活动”应用程序中其中包含容器和选项卡片段。每个此类页面都有自己的ViewModel,应与所有包含的片段共享。
这里的关键技巧是使用Activity而不是Fragment来保存我的ViewModel。
问题是我的活动可以有多个具有自己的模型的页面,并且始终保持特定页面的视图模型是浪费设备资源。
当用户离开页面时,是否有任何方法可以控制ViewModel的生命周期以销毁它?
我想使用容器片段而不是活动:
model = ViewModelProviders.of(getPageContainerFragment()).get(SharedViewModel.class);
Run Code Online (Sandbox Code Playgroud)
但是发现这个想法不是很好,因为所有子片段都应该了解父元素,而这可能不是很好。
是否有其他方法可以正确处理这种情况?
android model-view android-fragments android-architecture-components android-jetpack
我正在使用分页库来加载数据并填充我放置在nestedscrollview 中的recyclerview。但这就像,分页会自动工作,直到从 API 获取所有数据。我知道这是因为nestedscrollview。但不幸的是,我的布局需要滚动视图,因为我在这个片段中有一个不是 recyclerview 的顶部部分。这是我的布局
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
//have a layout here which scrolls with recyclerview
<Recyclerview />
</ConstraintLayout>
</NestedScrollView>
Run Code Online (Sandbox Code Playgroud)
当我不使用nestedscrollview 时,一切正常。googlesamples git repo regsrding 中有一个未解决的问题。
https://github.com/googlesamples/android-architecture-components/issues/215
有谁知道当回收视图位于带有 Android jetpack 分页库的滚动视图中时,我们如何实现分页。我知道我们可以实现传统类型的分页,将侦听器附加到nestedscrollview,但我希望使用架构组件库实现分页。 https://developer.android.com/topic/libraries/architecture/paging/
android android-layout android-architecture-components android-jetpack
在android-architecture-components/GithubBrowserSample 存储库中,Fragment#onViewCreated生命周期方法用于ViewModel实例化(具有Fragment的范围),用于Fragment使用数据绑定 + LiveData+组合的s ViewModel:
来自SearchFragment.kt该回购 ^:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
searchViewModel = ViewModelProviders.of(this, viewModelFactory)
...
}
Run Code Online (Sandbox Code Playgroud)
是否有任何官方的指南或共识哪个这些Fragment生命周期方法,如onAttach,onCreate,onViewCreated,或者onActivityCreated是实例化的最佳/最安全的地方Fragment的ViewModel使用ViewModelProviders.of(fragment, viewModelFactory)方法?(考虑到数据绑定 +LiveData组合,如果这有区别的话)
试图理解将ViewModel实例化放入任何早期生命周期方法(例如onAttach/ )的一般优点/缺点onCreate(super当然是在调用之后)。
提前致谢。
android android-fragments android-livedata android-viewmodel android-architecture-components
我无法理解这些注释之间的区别。在我的用例中,我想在表之间创建一对多关系。并找到了两个选项:一个是@ForeignKey,另一个是@Relation
我还发现,如果我更新该行(例如使用 OnCoflictStrategy.Replace),我将丢失该行的外键,这是真的吗?
Android 的导航组件能否用于在 BottomSheet 内导航(即在单个底部工作表中替换/添加片段)?
我知道如何BottomSheetDialogFragment使用<dialog>导航图中的标签启动一个。例如,下面的代码nav_graph.xml允许用户从一个BottomSheetDialogFragment(fragmentOne)导航到另一个BottomSheetDialogFragment(fragmentTwo)。FragmentTwo 作为第二个BottomSheet 打开,位于FragmentOne 的BottomSheet 之上。
但是,如果我想让 fragmentTwo 替换同一个 BottomSheet 中的 fragmentOne 怎么办?我将如何使用导航图完成此操作?
<navigation android:id="@+id/nav_graph"
app:startDestination="@id/fragmentOne">
<dialog android:id="@+id/fragmentOne"
android:name="com.example.navcomponentapp.FragmentOne"
android:label="fragment_fragment_one"
tools:layout="@layout/fragment_fragment_one">
<action android:id="@+id/action_fragmentOne_to_fragmentTwo2"
app:destination="@id/fragmentTwo"/>
</dialog>
<dialog android:id="@+id/fragmentTwo"
android:name="com.example.navcomponentapp.FragmentTwo"
android:label="fragment_fragment_two"
tools:layout="@layout/fragment_fragment_two"/>
</navigation>
Run Code Online (Sandbox Code Playgroud)
演示(这不是我想要的。我不想在另一个bottomSheet上打开一个bottomSheet

android android-navigation android-architecture-components android-jetpack android-navigation-graph
android ×10
android-architecture-components ×10
android-room ×2
android-architecture-navigation ×1
androidx ×1
model-view ×1
mvvm ×1