Kzaf
Kzaf

Reputation: 593

Android - Tasks.await blocks UI and ANR

I am trying to show in a view if there is a new update of the app in the playstore using AppUpdateManager.

I am using the below method that waits for the appUpdateInfoTask to finish and then continue with the UI.

private static AppUpdateInfo checkIfUpdateAvailable (Context context){
    try {
        AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(context);
        final Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo()
                .addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() {
                    @Override
                    public void onSuccess(AppUpdateInfo appUpdateInfo) {
                    }
                });
        try {
            return Tasks.await(appUpdateInfoTask);
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }catch (Exception e){
        e.printStackTrace();
        return null;
    }
}

This should return the AppUpdateInfo object when it is ready. However the await seems to block the whole UI.

What I cannot understand is why the app stuck on Tasks.await(appUpdateInfoTask), I have used the same method in other places as well and always run. Am I missing something here?

Upvotes: 1

Views: 4596

Answers (1)

NehaK
NehaK

Reputation: 2727

As the doc says :

https://developers.google.com/android/guides/tasks This method will be called synchronously (if it is called from UI Thread, then will block the UI)

So there are 2 options :

With your code :

You can also specify a timeout when blocking a task so that your application does not hang:

AuthResult authResult = Tasks.await(task, 500, TimeUnit.MILLISECONDS);

With following code (your code with modifications) :

    public interface UpdateAvailabilityInterface {
        void updateAvailable();
        void getAppUpdateInfo(AppUpdateInfo appUpdateInfo);
        void updateNotAvailable();
    }

    private static void checkIfUpdateAvailable(Context context, UpdateAvailabilityInterface updateAvailabilityInterface) {
        try {
            AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(context);
            final Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo()
                    .addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() {
                        @Override
                        public void onSuccess(AppUpdateInfo appUpdateInfo) {
//You will get the info here asynchronously..
                            if (updateAvailabilityInterface != null) {
                                updateAvailabilityInterface.getAppUpdateInfo(appUpdateInfo);

                                boolean updateIsAvailable = true; // add method to check if update is available or not
                                if (updateIsAvailable) {
                                    updateAvailabilityInterface.updateAvailable();
                                } else {
                                    updateAvailabilityInterface.updateNotAvailable();
                                }
                            }
                        }
                    });


//            try {
//                return Tasks.await(appUpdateInfoTask);
//            } catch (ExecutionException | InterruptedException e) {
//                e.printStackTrace();
//                return null;
//            }
        } catch (Exception e) {
            e.printStackTrace();
//            return null;
        }
    }

Note : I didn't try the above code, so please let me know if this doesn't work for you, I will try it by my self.

Caller will look like this :

        checkIfUpdateAvailable(context, new UpdateAvailabilityInterface() {
            @Override
            public void updateAvailable() {

                // Code when update is available
            }

            @Override
            public void getAppUpdateInfo(AppUpdateInfo appUpdateInfo) {
                // Get the AppUpdateInfo whenever it is available
//Write your code which will be executed after you get appUpdateInfo
            }

            @Override
            public void updateNotAvailable() {

                // Code when update is not available
            }
        });

    

Upvotes: 2

Related Questions