Completely Blocked (CB)

ECn Categories > Blocked Aplication (BA) > Completely Blocked (CB)

Refers to cases in which it is necessary to restart the app after it gets blocked. This case implies a crash or an Application-Not-Responding error (ANR), which means that the app stops and needs to be launched again.

Amount of Issues App List
5 (A7) AnntenaPod, (A49) Pockethub for Github, (A50) Kickstarter

Examples

PocketHub

Category: Productivity
v 0.3.1
Scenario: To see one repository with no internet connection
This video shows an example of an complete blocked application. At 5th second the user select in the app the "Repositories" tab, at 7 second selects one of the displayed repositories and clicks on it, the application shows a loading bar but at 8th second the app crashes.

The following code snippets show the classes and files that are involved in the generation of the previuos issue.

In order to see how this error is generated, we need to review all the flow event. First, as is shown in the following snippet there is a switch statement to know which fragment reacts when each tab is selected, for this specific case the “Repositories” tab is the second one so the second case is the one that reacts to “Repositories” tab click and as it can be seen at line 70 the selected one is “RepositoryListFragment”

app/src/main/java/com/github/pockethub/android/ui/user/HomePagerAdapter.java

   public Fragment getItem(int position) {
     Fragment fragment = null;
     switch (position) {
         case 0:
             fragment = defaultUser ? new UserReceivedNewsFragment()
                 : new OrganizationNewsFragment();
             break;
         case 1:
70.          fragment = new RepositoryListFragment();
             break;

So, know that the fragment has been initialized as we can see in the video there is a list of the repositories, this list is managed in an adapter that needs an implementation of the “onListItemClick” to know how to behave, and as it can be seen at line 162 when a repository is selected from the list a new intent is created and started for “RepositoryViewActivity”.

app/src/main/java/com/github/pockethub/android/ui/repo/RepositoryListFragment.java

    public void onListItemClick(ListView list, View v, int position, long id) {
        Repository repo = (Repository) list.getItemAtPosition(position);
        if (recentRepos != null) {
            recentRepos.add(repo);
        }
    
162.    startActivityForResult(RepositoryViewActivity.createIntent(repo), REPOSITORY_VIEW);
    }

Now that the intent has been created the “onCreate” method is called

app/src/main/java/com/github/pockethub/android/ui/repo/RepositoryViewActivity.java

protected void onCreate(Bundle savedInstanceState) {

Inside this method, a validation is made due to the result we now that the result is false then the else statement is executed, but at line 112 the main process start and a new Service is created and the repository information is retrieved using the “getRepository” method. Nevertheless, this method belongs to a library made with Retrofit, then this method make a request to a url but due to connectonless state the request cannot be made and the answer will be null. However as it can be seen in the rest of the snippet there is no exception handling for this type of error then a new exception is created and not handled the the app crashes

app/src/main/java/com/github/pockethub/android/ui/repo/RepositoryViewActivity.java

    if (owner.avatarUrl() != null && RepositoryUtils.isComplete(repository)) {
                checkReadme();
    } else {
        avatars.bind(getSupportActionBar(), owner);
        loadingBar.setVisibility(View.VISIBLE);
        setGone(true);
112.    ServiceGenerator.createService(this, RepositoryService.class)
                .getRepository(repository.owner().login(), repository.name())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(this.bindToLifecycle())
                .subscribe(response -> {
                    repository = response.body();
                    checkReadme();
                }, e -> {
                    ToastUtils.show(this, R.string.error_repo_load);
                    loadingBar.setVisibility(View.GONE);
                });
    }