执行器阻塞主线程-主线程等待时间过长触发ANR

问题描述 投票:0回答:1

我正在分析 firebase 日志 (crashalytics),我注意到与下面发布的功能相关的特定错误。

jdk.internal.misc.Unsafe.park

主线程等待时间过长触发ANR

 public class SendBackupData extends Service {
    private ScheduledExecutorService executorService;
    private static final WriteInLogFile wil = new WriteInLogFile();

    @Override
    public void onCreate() {
        super.onCreate();
        executorService = Executors.newSingleThreadScheduledExecutor();
    }

    
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        executeOperation();
        executorService.scheduleAtFixedRate(this::executeOperation, 0, 50, TimeUnit.MINUTES);
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        executorService.shutdown();
    }


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


    private void executeOperation() {
        Context context = getApplicationContext();
        try {
            SemaphoreBKP.getInstance(context).goIn();
            if (new Utilities(context).checkConnection()) {
                File dataDir = new File(new Constants(context).getArchiveFolder(false));
                File[] listOfFiles = dataDir.listFiles((dir, name) -> name.startsWith("REPORT") && name.endsWith(".zip"));
                if (listOfFiles != null) {
                    for (File listOfFile : listOfFiles) {
                        new FilesUtilities().splitBackupFiles(context, listOfFile.getName(), "arc");
                    }
                }

                File[] listOfFragments = dataDir.listFiles((dir, name) -> {
                    Pattern rexExp = Pattern.compile("(?:REPORT|\\G)(-[0-9]{2}-[0-9]{2}-[0-9]{4}-[a-zA-Z0-9]{8})(\\.zip)\\.[0-9]{3,6}\\.[0-9]{3,6}");
                    return name.startsWith("REPORT") && rexExp.matcher(name).matches();
                });

                if (listOfFragments != null) {
                    if (listOfFragments.length > 0) {
                        Arrays.sort(listOfFragments);
                        for (File currentFragment : listOfFragments) {
                            JSONObject jsonObject = new JSONObject();
                            jsonObject.put("filename", currentFragment.getName());
                            SendDataProcedure sendDataProcedure = new SendDataProcedure("1", "transmitBackupDevice", jsonObject.toString(), context);
                            boolean requestStatus = sendDataProcedure.postDataFromBackupPushDTS(currentFragment.getName().trim(), false);
                            if (requestStatus) {
                                if(currentFragment.exists()) {
                                    currentFragment.delete();
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            wil.WriteFile("SendBackupData - Exception: " + e.getMessage(), context);
        } finally {
            SemaphoreBKP.getInstance(context).goOut();
        }
    } }

我认为问题与我在主线程中执行非常“繁重”的操作有关,因此用户的 UI 被阻止。

我该如何解决这个问题?

我需要在后台运行这段代码,每50分钟一次,这个操作可能会或多或少地长,没有办法提前知道

java android service executorservice background-service
1个回答
0
投票

SemaphoreBKP goIn 会阻塞 UI 线程,将相关代码移动到另一个线程,使用如 AsyncTask。

© www.soinside.com 2019 - 2024. All rights reserved.