当一个Activity变为可见时如何运行一个函数?(onResume方法无法正常工作)

huangapple go评论79阅读模式
英文:

How to run a function, when an Activity gets visible? ( onResume does not work properly)

问题

我想在 Activity 可见时立即启动一个前台服务。我尝试通过重写 onResume 来实现这一点,但当我编译并运行我的应用时,即使屏幕被关闭,也会调用该方法。

如果屏幕被关闭,尝试启动前台服务时会出现 IllegalStateException

我将代码放在了 try-catch 块中。这基本上可以工作,但有时在屏幕可见之前不久就会调用它。

如何在每次我的 Activity 对用户可见时都运行一段代码呢?

英文:

I would like to start a foreground service, as soon as the Acitvity gets visible. I tried this, by overriding the onResume, but when I compile and run my app, it gets called even if the screen is turned off.

If the screen is turned off, I get IllegalStateException if I try to start a foreground service.

I wrapped the code inside a try-catch block. It mostly works, but sometimes it is not called after the screen gets visible, just right before that.

How is it possible to run a code every time when my Activity is visible by the user?

答案1

得分: 1

以下是翻译好的内容:

好吧,onResume 不是你的方法。这里 提供了一个很好的解释,介绍了 onCreateonStart 之间的基本区别。

正如你已经理解的那样,你需要的方法是 onStart,因为它会在活动对用户可见后直接被调用。

英文:

Well onResume is not you method. Here is a pretty neet explanation of basic differences between onCreate and onStart

As you've already understood the method you need is onStart because it gets called directly after the activity becomes visible to a user.

答案2

得分: 1

关于前台服务,从 Activity 的哪个回调函数开始它们并不重要,因为它们可以在应用程序在后台运行时工作。

如果在没有调用 startForeground 方法的情况下启动前台服务,可能会导致 IllegalStateException。请确保您的服务代码类似于以下代码:

class ExampleService : Service() {

   override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // 准备待定意图
        val pendingIntent = val pendingIntent: PendingIntent =
        Intent(this, ExampleActivity::class.java).let { notificationIntent ->
            PendingIntent.getActivity(this, 0, notificationIntent, 0)
        }

        // 构建前台服务运行时显示的通知
        val notification = 
            NotificationCompat.Builder(context, "channel_id")
               .setContentTitle("Title")
               .setContentText("Text")
               .setContentIntent(pendingIntent)
               .setSmallIcon(R.drawable.small_icon)
               .build()

        val notificationId = 42

        // 调用以告知系统将您的服务作为前台服务运行
        startForeground(notificationId, notification)
     
        // 实现业务逻辑  
        ....
    }
   
}

您可以在此处找到有关前台服务的更多信息:https://developer.android.com/guide/components/foreground-services

英文:

For Foreground Services it's not important from which callback of Activity you start them, because they can work even if app is working background.

You can get IllegalStateException if you start Foreground Service without calling startForeground method. Make sure the code of your Service contains code similar to the following:

class ExampleService : Service() {

   override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // prepare pending intent
        val pendingIntent = val pendingIntent: PendingIntent =
        Intent(this, ExampleActivity::class.java).let { notificationIntent ->
            PendingIntent.getActivity(this, 0, notificationIntent, 0)
        }

        // build notification to display while foreground service is running
        val notification = 
            NotificationCompat.Builder(context, "channel_id")
               .setContentTitle("Title")
               .setContentText("Text")
               .setContentIntent(pendingIntent)
               .setSmallIcon(R.drawable.small_icon)
               .build()

        val notificationId = 42

        // call tell the system run your service as foreground service
        startForeground(notificationId, notification)
     
        // implement the business logic  
        ....
    }
   
}

You can find more info about Foreground Services here: https://developer.android.com/guide/components/foreground-services

答案3

得分: 0

实际上,onStart 也可以在内容可见之前被调用。
当我想要在动画真正可见后才开始动画时,我也遇到了相同的问题。

如果你想要在运行代码之前确保视图已经可见,你可以按照以下方式操作:

requireActivity().getWindow().getDecorView().post(new Runnable() {
    @Override
    public void run() {
        // 你的代码
    }
});

这将创建一个排队的可运行对象,在所有其他 UI 组件加载完成后执行。你可以在 onViewCreated()onResume()onStart() 中调用它,没有关系。

英文:

Well actually also onStart can be called before the content is visible.
I had the same issue when I wanted to start an animation only after it is really visible..

If you want to be 100% sure that the view is visible before running your code, you can do the following:

        requireActivity().getWindow().getDecorView().post(new Runnable() {
            @Override
            public void run() {
                // your code
            }
        });

This will create a runnable that is queued up and runs after all other UI components are loaded. You can call this in onViewCreated(), onResume() or onStart() it doesn't matter.

huangapple
  • 本文由 发表于 2020年10月20日 22:00:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/64446783.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定