Skip to main content

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 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 MainApplication class, and Main Activity represents your MainActivity class. The MainApplication class creates your appโ€™s basic components and then passes control to the MobileSyncSDKManager singleton object. MobileSyncSDKManagerโ€”a subclass of 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 MobileSyncSDKManager 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 external client 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 MainApplication.
  • 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.

  • Overrides the Android Application.onCreate() function.
  • In its onCreate() override:
    • Calls the superclass onCreate() function.
    • Initializes Salesforce Mobile SDK by calling initNative() on the SDK manager object (MobileSyncSDKManager).
    • Provides optional commented code that you can reinstate to use your app as a Salesforce identity provider.
    • Provides optional commented code that you can reinstate to support push notifications.

Letโ€™s take a quick look at the code.

  1. From the Android Studio, 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, 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 MobileSyncSDKManager singleton object.

/**
 * Application class for our application.
 */
class MainApplication : Application() {
    companion object {
        private const val FEATURE_APP_USES_KOTLIN = "KT"
    }
    override fun onCreate() {
        super.onCreate()
        MobileSyncSDKManager.initNative(
            applicationContext,
            MainActivity::class.java,
        )
        MobileSyncSDKManager.getInstance().registerUsedAppFeature(FEATURE_APP_USES_KOTLIN)
    }
}

Once the MobileSyncSDKManager object is initialized, it takes off running, and we donโ€™t see the MainApplication class again. Notice that MobileSyncSDKManager requires two things to initialize itself.

  • An application context, so that it knows how to find your appโ€™s configuration.
  • A reference to the main activity classโ€”MainActivity.classโ€”which MobileSyncSDKManager 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 reentry. 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, and a button to clear the record display, and another one to log out.

You delve 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.

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.
  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:exported="true"
    android:theme="@style/SalesforceSDK">
	<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.

Resources

Salesforce ๋„์›€๋ง์—์„œ Trailhead ํ”ผ๋“œ๋ฐฑ์„ ๊ณต์œ ํ•˜์„ธ์š”.

Trailhead์— ๊ด€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์˜๊ฒฌ์— ๊ท€ ๊ธฐ์šธ์ด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด์ œ Salesforce ๋„์›€๋ง ์‚ฌ์ดํŠธ์—์„œ ์–ธ์ œ๋“ ์ง€ ์ƒˆ๋กœ์šด ํ”ผ๋“œ๋ฐฑ ์–‘์‹์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž์„ธํžˆ ์•Œ์•„๋ณด๊ธฐ ์˜๊ฒฌ ๊ณต์œ ํ•˜๊ธฐ