标签: android-jetpack

WorkManager 向 JobScheduler 添加了太多作业

我正在尝试使用 安排任务在特定时间运行WorkManager。我之所以使用它beginUniqueWork,是因为我只想为该特定 ID (uniqueWorkName) 一次安排一项任务。但enqueue多次调用后,有时会出现以下错误:

java.lang.IllegalStateException: Apps may not schedule more than 100 distinct jobs
    at android.os.Parcel.readException(Parcel.java:2012)
    at android.os.Parcel.readException(Parcel.java:1950)
    at android.app.job.IJobScheduler$Stub$Proxy.schedule(IJobScheduler.java:180)
    at android.app.JobSchedulerImpl.schedule(JobSchedulerImpl.java:44)
    at androidx.work.impl.background.systemjob.SystemJobScheduler.scheduleInternal(SystemJobScheduler.java:85)
    at androidx.work.impl.background.systemjob.SystemJobScheduler.schedule(SystemJobScheduler.java:64)
    at androidx.work.impl.Schedulers.scheduleInternal(Schedulers.java:98)
    at androidx.work.impl.Schedulers.schedule(Schedulers.java:69)
    at androidx.work.impl.WorkManagerImpl.rescheduleEligibleWork(WorkManagerImpl.java:398)
    at androidx.work.impl.utils.ForceStopRunnable.run(ForceStopRunnable.java:66)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)
Run Code Online (Sandbox Code Playgroud)

当我在 every 之后使用以下代码片段记录待处理作业的数量时enqueue,我注意到每次调用都会有 3 个新作业添加到列表中(虽然我预计总数会保持在 1)。

JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
int size = jobScheduler.getAllPendingJobs().size();
Run Code Online (Sandbox Code Playgroud)

这是我用来安排任务的代码:

val work = OneTimeWorkRequest.Builder(workerClass)
        .setInitialDelay(offset, TimeUnit.MILLISECONDS)
        .build()
WorkManager.getInstance()
        .beginUniqueWork(uniqueNameForTask, ExistingWorkPolicy.REPLACE, work)
        .enqueue()
Run Code Online (Sandbox Code Playgroud)

这里看起来有什么不对劲吗?我缺少什么?

android android-jobscheduler android-jetpack android-workmanager

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

使用导航参数传递数据时,如何解决 Kotlin 中的 ArrayList 无法转换为 android.os.Parcelable[] 错误?

我正在尝试使用这样的导航参数将类别数据(ArrayList)从一个片段发送到另一个片段。

fun setUpArgumentForSearchDestination(categories: ArrayList<Category>) {

    val searchDestination = fragmentView.findNavController().graph.findNode(R.id.destination_search)
        searchDestination?.addArgument(
            "allCategories", NavArgument.Builder()
            .setType(NavType.ParcelableArrayType(Category::class.java))
            .setDefaultValue(categories)
            .build())
        }
Run Code Online (Sandbox Code Playgroud)

在搜索片段中,我从参数中收到数据,如下所示:

       arguments?.let {
            // I get error in the code below:
            val categories = it.getParcelableArrayList<Category>("allCategories")

        }
Run Code Online (Sandbox Code Playgroud)

我收到错误消息:

java.util.ArrayList 无法转换为 android.os.Parcelable[]

我试图找到答案,即使我不确定这个问题的原因,似乎我必须Category像这个线程一样自定义我的类:Read &writing arrays of Parcelable objects

但我是一个初学者,并不太理解该线程的答案。我已经尝试实施parcelable,但仍然不起作用。这是我的Category

class Category() : Parcelable {

    var id : Int = 0
    var name : String = ""
    var parentID : Int = 0
    var imageURL : String = ""

    constructor(parcel: …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-navigation android-jetpack android-architecture-navigation

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

如何导航到导航抽屉项目单击上的活动

这是我的主要活动,我想导航到导航抽屉项目单击上的活动。我已经检查了实现此目的的旧方法,即使用 switch 语句和使用 onNavigationItemSelected 方法。我知道这是一个经常被问到的问题,但是在阅读了有关堆栈溢出的许多问题和解决方案后,我感到很困惑。我对片段以及通过单击导航抽屉中的项目启动活动所需的内容感到困惑。

MainActivity.java


import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;

import android.view.View;

import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;

import com.google.android.material.navigation.NavigationView;

import androidx.drawerlayout.widget.DrawerLayout;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.view.Menu;

public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as …
Run Code Online (Sandbox Code Playgroud)

java android android-jetpack androidx

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

如果我们使用基于单一活动的架构,视图模型可能很重

由于谷歌建议基于单一活动的应用程序。我有需要澄清的情况。

我有一个包含 3 个片段的活动,每个片段都链接到具有其他屏幕的不同片段。

  1. 我应该为每个选项卡只使用一个视图模型,还是应该使用一个具有不同屏幕的视图模型。

  2. 因为我只有一个活动并且视图模型驻留直到活动被销毁。我将为每个屏幕创建的所有 viewModel 都包含数据,直到活动被销毁。如果是这种情况,它会使我的应用程序变重。

java android mvvm kotlin android-jetpack

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

在片段Android java中初始化ViewModel

我想我的初始化视图模型对象中FirstFragment.java的文件BasicActivity。这四个代码都失败了。文档对我帮助不大。

mViewModel = new ViewModelProvider(this).get(MyViewModel.class);
mViewModel = new ViewModelProvider(requireActivity()).get(MyViewModel.class);
mViewModel = new ViewModelProvider(getActivity()).get(MyViewModel.class);
mViewModel = new ViewModelProvider(FirstFragment.class).get(MyViewModel.class);
Run Code Online (Sandbox Code Playgroud)

另一方面,public ViewModelProvider(@NonNull ViewModelStoreOwner owner)ViewModelProvider 以 ViewModelStoreOwner 为参数,在接口实现的FragmentActivity.java ViewModelStore getViewModelStore()方法中ViewModelStore可能是工厂模式。

@NonNull
        @Override
        public ViewModelStore getViewModelStore() {
            return FragmentActivity.this.getViewModelStore();
        }
Run Code Online (Sandbox Code Playgroud)

帮我初始化 ViewModel

java android mvvm fragment android-jetpack

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

我应该在使用 viewModel 时添加 binding.lifecycleOwner=this 吗?

在我看来,我应该binding.lifecycleOwner=this在使用viewModel.

我发现很多项目比如Code A都没有加binding.lifecycleOwner=this,为什么?

代码 A 来自项目https://github.com/enpassio/Databinding

代码 A

class AddToyFragment : androidx.fragment.app.Fragment() {

    private lateinit var binding: AddToyBinding
    ...

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = DataBindingUtil.inflate(
            inflater, R.layout.fragment_add_toy, container, false
        )

        setHasOptionsMenu(true)

        return binding.root
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        (requireActivity() as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)

        //If there is no id specified in the arguments, then it should be a new toy
        val chosenToy : ToyEntry? = arguments?.getParcelable(CHOSEN_TOY)

        //Get …
Run Code Online (Sandbox Code Playgroud)

android android-jetpack

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

Jetpack Compose 在方向改变时保存状态

我正在使用 Android Jetpack 的 Compose,并且一直在尝试弄清楚如何保存方向更改的状态。

我的思路是让一个类成为一个 ViewModel。因为当我使用 Android 的传统 API 时,这通常有效。

当信息发生更改时,我使用了 remember {} 和 mutableState {} 来更新 UI。请验证我的理解是否正确...

记住 = 保存变量并允许通过 .value 访问,这允许缓存值。但它的主要用途是在更改时不重新分配变量。

mutableState = 在发生变化时更新变量。

许多博客文章都说要使用@Model,但是,在尝试该方法时,导入会出错。所以,我添加了一个: ViewModel()

但是,我相信我记得 {} 阻止它按预期工作?

我能在正确的方向上得到一个点吗?

@Composable
fun DefaultFlashCard() {

    val flashCards = remember { mutableStateOf(FlashCards())}
    

    Spacer(modifier = Modifier.height(30.dp))

    MaterialTheme {


        val typography = MaterialTheme.typography
        var question = remember { mutableStateOf(flashCards.value.currentFlashCards.question) }



        Column(modifier = Modifier.padding(30.dp).then(Modifier.fillMaxWidth())
                .then(Modifier.wrapContentSize(Alignment.Center))
                .clip(shape = RoundedCornerShape(16.dp))) {
            Box(modifier = Modifier.preferredSize(350.dp)
                    .border(width = 4.dp,
                            color = Gray,
                            shape = RoundedCornerShape(16.dp))
                    .clickable( …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-viewmodel android-jetpack android-jetpack-compose

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

Android Jetpack:如何使用 PagingDataAdapter 在回收器视图中进行多项选择?

我想在我的 Android 应用程序中进行多项选择。我以前做过,但只使用了 ArrayAdapter。

我有一个 Flow 作为我的数据集,并使用 PagingDataAdapter 和 ViewHolder。

我的问题是,如果数据集不仅仅是一个列表并且我无法真正轻松地访问它,如何进行多重选择。

如果您想查找代码,请查看以下内容:

片段 适配器 ViewHolder ViewModel

paging android multi-select android-jetpack

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

我应该在 Android Jetpack Compose 中使用 ConstraintLayout 以获得更好的性能吗?

在 Jetpack Compose ConstraintLayout是构建复杂布局的推荐方式之前,因为它允许扁平化 UI 层次结构。请参阅管理复杂性:布局很重要文档部分。

布局花费特别长的时间的最常见情况是当 View 对象的层次结构相互嵌套时。每个嵌套的布局对象都会增加布局阶段的成本。层次结构越扁平,完成布局阶段所需的时间就越少。

在 Compose 世界中仍然如此吗?

android android-layout android-jetpack android-jetpack-compose

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

如何在 TopAppBar 的布局中心对齐标题?

TopAppBar(
       backgroundColor = Color.Transparent,
       elevation = 0.dp,
       modifier= Modifier.fillMaxWidth(),
       navigationIcon = {
               IconButton(
                   onClick = { TODO },
                   enabled = true,
               ) {
                   Icon(
                       painter = painterResource(id = R.drawable.icon_back_arrow),
                       contentDescription = "Back",
                   )
               }
           }
       },
       title = {
           Text(
               modifier = if (action == null) Modifier.fillMaxWidth() else Modifier,
               textAlign = if (action == null) TextAlign.Center else TextAlign.Start,
               maxLines = 1,
               text = "Hello"
           )
       },
       actions = {
           action?.run {
               Text(
                   modifier = Modifier
                       .padding(horizontal = 16.dp)
                       .clickable(onClick = …
Run Code Online (Sandbox Code Playgroud)

android android-jetpack android-jetpack-compose

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