📢 Attention Salesforce Certified Trailblazers! Maintain your credentials and link your Trailhead and Webassessor accounts by April 19th. Learn more.
close
•
Start tracking your progress
Trailhead Home
Trailhead Home

Understand Forcedroid Apps

Learning Objectives

After completing this unit, you'll be able to:

  • Describe the overall flow of a native Salesforce Mobile SDK for Android app
  • Identify the two main classes of a forcedroid app
  • List four tasks that the SalesforceSDKManager object handles for you

Overview of Application Flow

You’ve created and run a new forcedroid native app. Wondering what makes it tick?

Here’s a diagram that shows, at a high level, how the app startup flow works.

Android application flow

In your app, the “Application Object” is an instance of your MyTrailNativeApp class, and “Main Activity” represents your MainActivity class. The MyTrailNativeApp class creates your app’s basic components and then passes control to the SalesforceSDKManager singleton object. SalesforceSDKManager in turn launches the Salesforce login flow, and—if user authentication succeeds—hands off control to the MainActivity class. MainActivity instantiates and displays everything that appears on your list view screen.

Passcodes, login, logout, and cleanup are tasks that the SalesforceSDKManager singleton manages. Internal class objects take care of OAuth protocols. As you can see, the passcode part of the flow is optional. It occurs only if your connected app enables passcodes, and a Salesforce admin can revert that policy at any time. In any case, though, you have nothing to worry about for passcodes. Mobile SDK provides complete implementation behind the scenes.

What’s in a Forcedroid App?

A forcedroid native app implements only basic functionality. The user can switch between viewing a list of Contacts and a list of Accounts, and that’s it. However, the app gives you a springboard for diving straight into your own awesome ideas. You can enhance your app by:
  • Performing CRUD (Create, Read, Update, Delete) operations on Salesforce records
  • Adding custom activities
  • Calling other components
  • Doing anything else that your project scope, your own imagination, and current technology allow

When forcedroid creates a native app, it makes a copy of a Mobile SDK template project and customizes it to match your command line input. Let’s look at some of the standard items that this cookie cutter produces.

Every forcedroid app defines two public Android classes:
  • An application class that extends android.app.Application. This class serves as the app’s entry point. In your app, this class is named MyTrailNativeApp.
  • A main activity class that extends android.app.Activity. This class defines a screen and contains most of the app’s custom logic. In forcedroid apps, this class is named MainActivity. It extends SalesforceActivity, which in turn extends android.app.Activity.

As with any Android app, the AndroidManifest.xml file designates the app’s configuration, specifying the application class and all activity classes.

The Application Class

Your application class accomplishes two main tasks:

  • Calls initNative() to initialize the app
  • Passes in the app’s implementation of KeyInterface
Let’s take a quick look at the code.
  1. From the Android Studio Welcome screen, select Import project (Eclipse ADT, Gradle, etc.). Or, if Android Studio is already open, click File | Open....
  2. Browse to the target directory you specified at the forcedroid command prompt and select it. (Hint: The target directory is “TrailAndroidApps”, unless you broke the rules.)
  3. Click Choose.
  4. When the Android Studio editing window comes up, open the Project View (View | Tool Windows | Project).
  5. In the Project window, expand app | java | com.mytrail.android | MainApplication.java, and then double-click MainApplication.

The MainApplication class is pretty simple. It defines an override of a single base class method, onCreate(). What does the override do? It calls the super class OnCreate() method and then initializes the SalesforceSDKManager singleton object.

/**
 * Application class for our application.
 */
public class MainApplication extends Application {

	@Override
	public void onCreate() {
		super.onCreate();
		SalesforceSDKManager.initNative(getApplicationContext(), new NativeKeyImpl(), MainActivity.class);

		/*
		 * Un-comment the line below to enable push notifications in this app.
		 * Replace 'pnInterface' with your implementation of 'PushNotificationInterface'.
		 * Add your Google package ID in 'bootonfig.xml', as the value
		 * for the key 'androidPushNotificationClientId'.
		 */
		// SalesforceSDKManager.getInstance().setPushNotificationReceiver(pnInterface);
	}
}
Once the SalesforceSDKManager object is initialized, it takes off running, and we don’t see the MainApplication class again. Notice that SalesforceSDKManager requires three things to initialize itself:
  • An application context, so that it knows how to find your app’s configuration.
  • An instance of a class that implements KeyInterface—in our case, NativeKeyImpl, which is implemented in this file as follows:
    class NativeKeyImpl implements KeyInterface {
    
    	@Override
    	public String getKey(String name) {
    		return Encryptor.hash(name + "12s9adpahk;n12-97sdainkasd=012", name + "12kl0dsakj4-cxh1qewkjasdol8");
    	}
    }
    This object provides an encryption key for securing the user’s data.
  • A reference to the main activity class—MainActivity.class—which SalesforceSDKManager uses at the end of the login flow to kick off your app’s custom logic.
From this small amount of free code, your app gets passcode, login and logout, OAuth, and user data encryption. Not a bad deal, eh?

The Main Activity Class

Luckily, forcedroid is smart enough to make your MainActivity class extend SalesforceActivity. That bit of good fortune means that you get many gnarly things for free. For example, SalesforceActivity automatically handles pause and resume events, including any necessary passcode re-entry. If you had instead used some non-Salesforce activity base class—not a forbidden strategy, but not recommended, either—you’d be writing that code yourself. You can define as many activity classes as your app demands. However, it’s a good idea for every activity to extend a Mobile SDK base class, such as SalesforceActivity or SalesforceListActivity.

The MainActivity class busies itself with sending a REST query to Salesforce, and then processing the response. It uses the records it receives from Salesforce to populate a list view. It also provides two buttons that let the user choose to query either Accounts or Contacts, as well as a button to clear the record display, and another one to log out.

We’ll go into the details of REST interaction later. For now, though, let’s see how and where these UI buttons are configured.
  1. In the Android Studio Project window, expand MyTrailNative | res | layout, and then double-click main.xml.
  2. At the bottom of the editor window, select the Text tab.
The Text tab gives you a split window with a visual designer on the right and the view’s XML configuration file on the left. A click on any area in the visual designer highlights the area’s XML configuration. If you click the FETCH CONTACTS button, for example, the editor highlights a <LinearLayout>/<Button> node. Attributes on the node specify the button’s characteristics—appearance, identification, and behavior. Check out the Android developer documentation to learn more about UI configuration details.
If you click inside the view header—for example, on the Logout button—the editor highlights an <include> node:
<include layout="@layout/header" />
This node tells you that the header is defined in another XML file. Judging from the layout attribute, you can readily find header.xml in the same path as main.xml. Pretty simple!

The App Manifest

Your project’s AndroidManifest.xml file reveals the app’s most basic configuration: its name, icon, main activity, minimum and target Android API versions, and so on. See for yourself!
  1. In the Android Studio Project window, expand app | manifests.
  2. Double-click AndroidManifest.xml.
In the root <manifest> node, right after the namespace declaration, you’ll see your app’s package name declared:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mytrail.android"
    android:versionCode="1"
    android:versionName="1.0"
    android:installLocation="internalOnly">
The <manifest> root element contains an <application> node that sets your app’s basic configuration. At the top level, this node sets the attribute that tells the Android overlord the name of the forcedroid application startup class.
<application android:icon="@drawable/sf__icon"
    android:label="MyTrailNative"
    android:name=".MainApplication"
    ...
The “.” prefix tells Android to prepend the app’s package name—com.mytrail.android—to this class path.

Also, every activity you or forcedroid defines gets a description here. For example, the sole application/activity node in this case represents the first activity that appears after login. As you see, the activity’s android:name property references your main activity’s class name. Here’s the application/activity XML fragment from a forcedroid AndroidManifest.xml file.

<!-- Launcher screen -->
<activity android:name=".MainActivity"
    android:label="@string/app_name"
	android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
	<intent-filter>
		<action android:name="android.intent.action.MAIN" />
		<category android:name="android.intent.category.LAUNCHER" />
	</intent-filter>
</activity>

Everything else you see in the default manifest file is standard Android configuration. As with any Android app, you can add your app’s own components to the <application> node, such as custom activities, services, and receivers.

Now that you've learned what's in a forcedroid app, let’s move on to the info you’ve been waiting for: how to access Salesforce data.

retargeting