输入调度超时 ANR

Posted

技术标签:

【中文标题】输入调度超时 ANR【英文标题】:Input dispatching timed out ANR 【发布时间】:2018-04-26 08:00:06 【问题描述】:

我的应用程序中经常出现以下 ANR

Input dispatching timed out (Waiting to send key event because the focused window has not finished processing all of the input events that were previously delivered to it. Outbound queue length: 0. Wait queue length: 1.)

日志说 onActivityStopped 方法中的问题

这是我在这个方法中添加的代码

try 
            boolean foreground = new ForegroundCheckTask().execute(getApplicationContext()).get();
            if(!foreground) 

                AdServerManager.getInstance().incrementImpression(activity, ForSaleDataManager.getInstance().getBannerImpression(),
                        ForSaleDataManager.getInstance().getOfferImpression(), new View.OnClickListener() 
                            @Override
                            public void onClick(View v) 

                                ForSaleDataManager.getInstance().clearOfferImpression();
                                ForSaleDataManager.getInstance().clearBannerImpression();
                            
                        );

                String lastOffers = TextUtils.join("," , ForSaleDataManager.getInstance().getVisitedOffersIds());
                //Appboy.getInstance(activity).getCurrentUser().setCustomUserAttribute(AppBoyAttributeName.LAST_TEN_OFFER_IDS.getValue() , lastOffers);
                ForSaleDataManager.getInstance().clearVisitedOffersIds();

                String lastCategories = TextUtils.join("," , ForSaleDataManager.getInstance().getVisitedCategoriesIds());
                //Appboy.getInstance(activity).getCurrentUser().setCustomUserAttribute(AppBoyAttributeName.LAST_TEN_CATEGORY_IDS.getValue() , lastCategories);
                ForSaleDataManager.getInstance().clearVisitedCategoriesIds();

                String lastSearch = TextUtils.join("," , ForSaleDataManager.getInstance().getVisitedSearchTerms());
                //Appboy.getInstance(activity).getCurrentUser().setCustomUserAttribute(AppBoyAttributeName.LAST_TEN_SEARCH_TERMS.getValue() , lastSearch);
                ForSaleDataManager.getInstance().clearVisitedSearchTerms();

                // clear landing page
                PhoneUtils.addBooleanToSharedPreference(activity, ForSaleConstants.IS_CATEGORIES_LANDING_SHOWEN, false);
                PhoneUtils.addBooleanToSharedPreference(activity, ForSaleConstants.IS_LISTING_LANDING_SHOWEN, false);
                PhoneUtils.deleteWithPrefixFromSharedPreference(activity, ForSaleConstants.IS_SUB_CATEGORIES_LANDING_SHOWEN_PREFIX, false);
                PhoneUtils.deleteWithPrefixFromSharedPreference(activity, ForSaleConstants.IS_SUB_CATEGORIES_LANDING_SHOWEN, false);


                // reset for last activity
                PhoneUtils.addBooleanToSharedPreference(activity, ForSaleConstants.SET_LAST_ACTIVITY_CALLED, false);
            
         catch (InterruptedException e) 
            e.printStackTrace();
         catch (ExecutionException e) 
            e.printStackTrace();
        

我的应用程序的系统要求,我必须向服务器发送一些数据并清除本地数据,因此我实现了接口 Application.ActivityLifecycleCallbacks

谁能建议如何在不产生 ANR 的情况下满足我的系统要求?

编辑

这是我把它放在AsyncTask中后的代码,它不起作用

@Override
    public void onActivityStopped(final Activity activity) 

        //new AsyncTask<Void, Void, Void>() 

            //@Override
            //protected Void doInBackground(Void... voids) 

                try 
                    boolean foreground = new ForegroundCheckTask().execute(getApplicationContext()).get();
                    if(!foreground) 

                        AdServerManager.getInstance().incrementImpression(activity, ForSaleDataManager.getInstance().getBannerImpression(),
                                ForSaleDataManager.getInstance().getOfferImpression(), new View.OnClickListener() 
                                    @Override
                                    public void onClick(View v) 

                                        ForSaleDataManager.getInstance().clearOfferImpression();
                                        ForSaleDataManager.getInstance().clearBannerImpression();
                                    
                                );

                        String lastOffers = TextUtils.join("," , ForSaleDataManager.getInstance().getVisitedOffersIds());
                        //Appboy.getInstance(activity).getCurrentUser().setCustomUserAttribute(AppBoyAttributeName.LAST_TEN_OFFER_IDS.getValue() , lastOffers);
                        ForSaleDataManager.getInstance().clearVisitedOffersIds();

                        String lastCategories = TextUtils.join("," , ForSaleDataManager.getInstance().getVisitedCategoriesIds());
                        //Appboy.getInstance(activity).getCurrentUser().setCustomUserAttribute(AppBoyAttributeName.LAST_TEN_CATEGORY_IDS.getValue() , lastCategories);
                        ForSaleDataManager.getInstance().clearVisitedCategoriesIds();

                        String lastSearch = TextUtils.join("," , ForSaleDataManager.getInstance().getVisitedSearchTerms());
                        //Appboy.getInstance(activity).getCurrentUser().setCustomUserAttribute(AppBoyAttributeName.LAST_TEN_SEARCH_TERMS.getValue() , lastSearch);
                        ForSaleDataManager.getInstance().clearVisitedSearchTerms();

                        // clear landing page
                        PhoneUtils.addBooleanToSharedPreference(activity, ForSaleConstants.IS_CATEGORIES_LANDING_SHOWEN, false);
                        PhoneUtils.addBooleanToSharedPreference(activity, ForSaleConstants.IS_LISTING_LANDING_SHOWEN, false);
                        PhoneUtils.deleteWithPrefixFromSharedPreference(activity, ForSaleConstants.IS_SUB_CATEGORIES_LANDING_SHOWEN_PREFIX, false);
                        PhoneUtils.deleteWithPrefixFromSharedPreference(activity, ForSaleConstants.IS_SUB_CATEGORIES_LANDING_SHOWEN, false);


                        // reset for last activity
                        PhoneUtils.addBooleanToSharedPreference(activity, ForSaleConstants.SET_LAST_ACTIVITY_CALLED, false);
                    
                 catch (InterruptedException e) 
                    e.printStackTrace();
                 catch (ExecutionException e) 
                    e.printStackTrace();
                

                //return null;
        //    
        //.execute();


    

【问题讨论】:

【参考方案1】:

将所有这些逻辑移到后台线程中。这就是您解决来自您的代码的任何 ANR 的方法。

【讨论】:

它不起作用我在 AsyncTask 中移动了以前的代码,它不起作用,当我将应用程序移动到后台并将其带回前台时,它会关闭并再次重新打开,请检查我的编辑查看我的代码 @AmiraElsayedIsmail:您的第二个代码块似乎与第一个代码块相同,除了更多的缩进和一些 cmets。除此之外,我不知道“它不起作用”是什么意思,我也不知道“它关闭并重新打开”是什么意思。 我使用了第二个代码块,但肯定没有注释部分,并且不起作用的代码是 doinBackground() 中的代码,以及我在后台将应用程序置于后台的最后一点在 HomeActivity 上,然后当我将它带回前台时,应用程序打开 SplashActivity 并重新开始 @AmiraElsayedIsmail:“不起作用的代码是 doinBackground() 中的代码”——这没有解释“不起作用”的含义。请记住,您不应该从后台线程引用Activity,因为它可能会在您的线程完成之前被销毁。相反,首先从活动中收集您需要的数据,然后分叉线程并处理收集的数据。

以上是关于输入调度超时 ANR的主要内容,如果未能解决你的问题,请参考以下文章

ANR 输入调度超时

Android:ANR 输入调度超时

Android 4.4 上的 ANR 输入调度超时

输入调度超时导致的 ANR - 在尝试获取我的公共 IP 地址时

com.android.inputmethod.latin 中的 ANR 原因:输入调度超时

ANR 输入超时