Insider's Guide To Udacity Android Developer Nanodegree Part 3 - Making the Baking App
Written by Nikos Vaggalis   
Monday, 03 July 2017
Article Index
Insider's Guide To Udacity Android Developer Nanodegree Part 3 - Making the Baking App
Step 1 Fragments
Step 2 - Libraries & Networking
Step 3 - Adding Exoplayer
Step 4 - Widgets
Step 5 - The Widget Provider
Step 6 - UI Testing
Step 7 - Testing Intents


Step 7 - Testing Intents

There's also testing Intents with Stubs and Verifications.

image30image31

 

First let's define the stub:


@Before
    public void stubAllExternalIntents() {
        // By default Espresso Intents does not stub
        // any Intents. Stubbing needs to be setup before
        // every test run.
        // In this case all external Intents will be blocked.
        intending(not(isInternal())).respondWith(
         new Instrumentation.ActivityResult(
                                          Activity.RESULT_OK, null));
    }

   
which checks that when a recipe such as 'Nutella Pie' is clicked it loads the RecipeDetailActivity:

 


@Test
    public void checkIntent_RecipeDetailActivity() {
        onView(ViewMatchers.withId(R.id.recipe_recycler))
              .perform(RecyclerViewActions
                             .actionOnItemAtPosition(0,click()));
        intended(hasComponent(
                           RecipeDetailActivity.class.getName()));
    }
   


hasComponent does all the heavy lifting in looking at the runtime to find an activity with the given class name, checking that RecipeDetailActivity is in fact loaded.

What's missing from the tests is the Intent Verification part which checks that the receiving activity has in fact received all the data we have sent it. Think of it like a SQL query: 
    select Data from Activity where ...
and then check that Data is the one we have sent.

Take a look at a good summary of the differences between Stubs and Verifications:

image32

Building the Project

Finally it's time to build the project. What soon becomes apparent is the wide fragmentation of the Android Support libraries, a potential source of confusion amongst developers.

There's v4 Support Library, v7 Support Libraries, v7 appcompat library, v7 cardview library, v7 recyclerview library, Design library and so on. So mix ups like the following are bound to occur:

"Note that the AppCompat library has an implicit dependency on the support-v4 library. The support-v4 declaration however does not necessarily need to be declared. Since the release of the support-v4 version 24.2.0, the library has been divided into separate modules: support-compat, support-core-utils, support-core-ui, support-media-compat, and support-fragment. However, because the AppCompat library usually depends on support-fragment, which still contains a dependency to all the other modules, you currently cannot take advantage of this change to reduce the number of overall dependencies."

For more on the matter check this and this for the difference between android-support-v7-appcompat and android-support-v4

Some Final Issues

Initially I had the Toolbar's  View.OnClickListener() inner classes:


myToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fm =
                             getSupportFragmentManager();
                if (findViewById(R.id.fragment_container2)==null) {
                    if (fm.getBackStackEntryCount() > 1) {
                        //go back to "Recipe Detail" screen
                        fm.popBackStack(STACK_RECIPE_DETAIL, 0);
                    } else if (fm.getBackStackEntryCount() > 0) {
                        //go back to "Recipe" screen
                        finish();
                    }
                }
                else {
                    //go back to "Recipe" screen
                    finish();
                }
            }
        });
    }
  


replaced by lambda expressions :  

   
     myToolbar.setNavigationOnClickListener(v -> {
            FragmentManager fm = getSupportFragmentManager();
            if (findViewById(R.id.fragment_container2)==null) {
                if (fm.getBackStackEntryCount() > 1) {
                    //go back to "Recipe Detail" screen
                    fm.popBackStack(STACK_RECIPE_DETAIL, 0);
                } else if (fm.getBackStackEntryCount() > 0) {
                    //go back to "Recipe" screen
                    finish();
                }
            }
            else {
                //go back to "Recipe" screen
                finish();
            }
        });
    }


but after a few builds where everything went ok, strange errors started appearing that were stopping the build from completing:

 
java.lang.NoSuchMethodError: No direct method <init>
(Ljava/lang/Object;)V in class
Lcom/example/android/recipe/ui/-$Lambda$0;
or its super classes (declaration of
'com.example.android.recipe.ui.-$Lambda$0' appears in
/data/app/com.example.android.recipe-1/base.apk)

 

image32a

The remedy was to revert to the old inner class code.


Another problem that hindered building was the Antivirus of my machine, Avira in this instance. The issue resolves if you temporarily disable it for the building to proceed.

image33


The colors of the UI were chosen according to material design, taken from the excellent Colorion site which hosts a great range of color combinations.

image34  
The few icons used came from Google's own material design icons collection.


What we've covered

This part of the Nanodegree - and this write up - has covered a lot: activities, fragments, backstacks, adapters, resposive design and layouts, Retrofit, conversion between JSON, POJO and Parcelable, media players and media sessions, services, pendingintents, IPC with widgets, remoteviews, broadcasts, testing views and intents and the list goes on.

This goes to show the depth, holistic and elaborate approach that the Nanodegree adopts.The lessons were of high standard, despite a few omissions that IMHO should had been covered, while on the other hand there were lessons not of immediate value in completing the project: Places, FCM and Publish Your App. However, the essential building blocks, the blocks which without you cannot build an app were solidly conveyed. I can imagine  an application without FCM or GeoFences, but one without Fragments?

As apparent, my version of Baking App is not going to get nominated for the 'Best Looking App' category, as again, I aimed for functionality and building a proof of concept than beauty. What can I say, I've always been a backend developer. Is that an excuse?I don't know...

So that's two out of five in the Nanodegree series completed.

Coming next we have Gradle fundamentals: "Learn the syntax and semantics of Gradle build scripts, and understand the lifecycle of a Gradle build."

Looking forward.

 

More Information

Nikos Vaggalis' "Baking App" GitHub repository

Android Developer Nanodegree

Related Articles

Insider's Guide To Udacity Android Developer Nanodegree - 1

Insider's Guide To Udacity Android Developer Nanodegree - 2

 

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

 

 

Banner

 

espbook

 

Comments




or email your comment to: comments@i-programmer.info



Last Updated ( Monday, 20 November 2017 )