后台服务冻结/滞后 android 应用程序

Posted

技术标签:

【中文标题】后台服务冻结/滞后 android 应用程序【英文标题】:Background service is freezing/lagging android app 【发布时间】:2021-08-28 04:08:53 【问题描述】:

我一直在开发一个有服务的 android 应用程序,我想永远运行它

我正在使用广播接收器oncreate of service中获取屏幕开关意图,并使用警报管理器 在 onstartcommand 内每 25 秒后启动 服务本身 并在 onstartcommand 中执行我的其他操作。我已将所有代码放在onstartcommand 中的一个线程 中。但问题是,一旦服务在后台运行几个小时,我重新打开应用程序应用程序开始滞后并变得非常慢。在启动服务之前,该应用运行良好。

我的代码简介如下-

public class MyService extends Service 

    @Nullable
    @Override
    public IBinder onBind(Intent intent) 
        return null;
    

    AlarmManager alarmManagerMain;
    BroadcastReceiver receiver;
    Thread t;
    Thread thread;

        @Override
    public void onCreate()  
        super.onCreate();
        t = new Thread(() -> 
            HandleReceiver();
        );
        t.start();
        CreateNotificationChannel();
        startNotification();
    

    private void HandleReceiver() 
        try 
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(Intent.ACTION_SCREEN_ON);
            intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
            receiver = new BroadcastReceiver() 
                @Override
                public void onReceive(Context context, Intent intent) 
                    if(intent.getAction().equals(Intent.ACTION_SCREEN_ON))
                    
                        // ...
                        // My Code
                        // ...
                        // Starting Service to call onStartCommand
                        Intent serviceIntent = new Intent(context, MyService.class);
                        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                        
                            startForegroundService(serviceIntent);
                        
                        else
                        
                            startService(serviceIntent);
                        
                    
                    else if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
                    
                        // ...
                        // My Code
                        // ...
                    
                
            ;
            MyService.this.registerReceiver(receiver, intentFilter);
        
        catch (Exception ignore)  
    

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) 
        Runnable runnable = () -> 
            if(allowNotificationAndAlerts)
            
                // My Code
            
            // This function is to start the service even after the system kills it
            startAlarm();
        ;
        thread = new Thread(runnable);
        thread.start();
        return super.onStartCommand(intent, flags, startId);
    

    private void startAlarm()
    
        AlarmManager alarmManager = (AlarmManager) MyService.this.getSystemService(Service.ALARM_SERVICE);
        Intent myIntent = new Intent(MyService.this, MyBroadCastReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(MyService.this, 1, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.add(Calendar.SECOND, 25);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
         else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 
            alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
         else 
            alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
        
    

    @Override
    public void onDestroy() 
        stopForeground(false);
        unregisterReceiver(receiver);
        super.onDestroy();
    

我的问题是 -

    我怎样才能优化服务以使其在后台永远运行而不会导致应用程序延迟 有什么方法可以通过系统或其他任何方法来获得screen on off intent,而不是通过广播接收器运行服务

【问题讨论】:

【参考方案1】:

我得到了答案 我能够通过从清单中的服务中删除“android:process=:remote”行并将共享首选项更改为数据库来解决这个问题,问题可能是因为共享首选项不是进程安全的

【讨论】:

以上是关于后台服务冻结/滞后 android 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

在后台Android中进行繁重处理时UI冻结

Android Shake(Sensor) 服务,用于在应用程序后台进行抖动检测

如何检测android中的活动冻结和滞后原因?

一段时间后滞后 Android 应用

后台抓取导致应用程序冻结而不是前台抓取

后台线程方法无法解决冻结问题