Android SDK Complete Reference Cheatsheet: Essential Tools, Libraries, and APIs

Introduction

The Android Software Development Kit (SDK) is a comprehensive collection of tools, libraries, and APIs that developers use to create applications for the Android platform. This cheatsheet provides a comprehensive overview of the Android SDK components, essential tools, key APIs, and best practices. Understanding these elements is crucial for efficient Android app development, debugging, and optimization. Whether you’re starting your first Android project or looking to deepen your knowledge of specific SDK features, this guide will serve as a valuable reference.

Android SDK Components Overview

SDK Manager Core Components

ComponentDescriptionKey Features
SDK ToolsEssential development toolsADB, DDMS, AVD Manager, Lint
SDK Platform-ToolsInterface with Android devicesADB, Fastboot, Systrace
SDK PlatformAndroid API libraries and system imagesAPI level-specific libraries, system images
SDK Build-ToolsCompile and package Android appsdx, aapt, dexdump, zipalign
EmulatorVirtual device for testingHardware acceleration, snapshots, multi-display support
System ImagesOS images for emulatorx86/ARM architectures, Google APIs, Google Play
SourcesAndroid platform source codeReference material for platform behavior
ExtrasAdditional libraries and toolsSupport library, Play services, constraint layout

SDK Directory Structure

android-sdk/
├── build-tools/       # Version-specific build tools
├── emulator/          # Android emulator files
├── licenses/          # SDK license agreements
├── patcher/           # Dependency patch files
├── platform-tools/    # ADB and other device tools
├── platforms/         # API-specific Android platforms
├── sources/           # Android source code
├── system-images/     # Emulator system images
├── tools/             # Core development tools
└── extras/            # Additional libraries

Essential Android SDK Tools

Android Debug Bridge (ADB)

# Device Management
adb devices                     # List connected devices
adb -s <device-id> <command>    # Send command to specific device
adb connect <ip>:<port>         # Connect to device over network
adb disconnect                  # Disconnect all network devices

# App Installation and Management
adb install -r app.apk          # Install/replace application
adb uninstall com.example.app   # Uninstall application
adb shell pm list packages      # List installed packages
adb shell am start -n com.package.name/.ActivityName   # Launch activity

# File Transfer
adb push <local> <remote>       # Copy file/dir to device
adb pull <remote> <local>       # Copy file/dir from device

# Logging
adb logcat                      # View device logs
adb logcat -v threadtime        # Detailed logs with timestamps
adb logcat "*:E"                # Show only errors
adb logcat -c                   # Clear log buffer

# Debugging
adb shell dumpsys                 # Dump system information
adb shell dumpsys meminfo         # Memory usage info
adb shell dumpsys activity        # Activity manager state
adb shell dumpsys battery         # Battery status
adb shell screencap -p /sdcard/screen.png   # Take screenshot
adb shell screenrecord /sdcard/video.mp4    # Record screen

Emulator

# Starting emulator from command line
emulator -avd <avd_name>                    # Start specific AVD
emulator -avd <avd_name> -wipe-data         # Factory reset emulator
emulator -list-avds                         # List available AVDs
emulator -avd <name> -camera-back webcam0   # Use webcam as camera

# Advanced emulator options
emulator -avd <name> -no-snapshot-load      # Start without snapshot
emulator -avd <name> -gpu host              # Use host GPU
emulator -avd <name> -netdelay umts         # Simulate network delay
emulator -avd <name> -netspeed gsm          # Simulate network speed
emulator -avd <name> -dns-server 8.8.8.8    # Set custom DNS server

Build Tools

# APK Signing
apksigner sign --ks keystore.jks app.apk
apksigner verify --verbose app.apk

# APK Analysis
aapt dump badging app.apk      # Show APK manifest info
aapt dump resources app.apk    # Show app resources
aapt dump xmltree app.apk AndroidManifest.xml  # Show manifest XML

# APK Optimization
zipalign -v 4 input.apk output.apk  # Optimize APK

# Bundletool (for App Bundles)
bundletool build-apks --bundle=app.aab --output=app.apks
bundletool install-apks --apks=app.apks

DDMS (Dalvik Debug Monitor Server)

Legacy tool mostly replaced by Android Studio profiling tools, but still useful for:

  • Thread and heap monitoring
  • Screen capturing
  • Simulating phone calls and SMS
  • File explorer functionality
  • Location spoofing

SDK Manager in Command Line

# List installed and available packages
sdkmanager --list

# Install packages
sdkmanager "platform-tools" "platforms;android-33"
sdkmanager "system-images;android-33;google_apis;x86_64"

# Update all installed packages
sdkmanager --update

# Uninstall packages
sdkmanager --uninstall "platforms;android-30"

API Levels and Platform Versions

API LevelVersion NameVersion NumberKey Features
33TiramisuAndroid 13Themed app icons, per-app language, improved privacy
32Snow ConeAndroid 12LLarge screen optimizations, taskbar
31Snow ConeAndroid 12Material You, Privacy Dashboard, approximate location
30RAndroid 11Conversation notifications, one-time permissions, wireless debugging
29QAndroid 10Dark theme, gesture navigation, privacy controls
28PieAndroid 9Indoor positioning, display cutout, multi-camera
27OreoAndroid 8.1Neural networks API, shared memory API
26OreoAndroid 8.0Picture-in-picture, notification channels, autofill
24-25NougatAndroid 7.0-7.1.2Multi-window, notification replies, Vulkan API
23MarshmallowAndroid 6.0Runtime permissions, Doze mode, fingerprint authentication
21-22LollipopAndroid 5.0-5.1Material Design, ART runtime, WebView independent updates
19-20KitKatAndroid 4.4-4.4.4Immersive mode, transitions, print framework
16-18Jelly BeanAndroid 4.1-4.3Project Butter, Google Now, restricted profiles
14-15Ice Cream SandwichAndroid 4.0-4.0.4Unified UI for phones/tablets, face unlock
10-13HoneycombAndroid 3.0-3.2.6Fragment API, action bar, animations framework
8-9GingerbreadAndroid 2.3-2.3.7NFC support, download manager, multiple cameras
5-7Froyo/EclairAndroid 2.0-2.2HTML5 support, Live wallpapers, App2SD

Key Android SDK Libraries and APIs

Core UI Components

// Setting up RecyclerView
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = MyAdapter(dataList)

// ViewPager2 with Fragments
val viewPager = findViewById<ViewPager2>(R.id.viewPager)
val adapter = ViewPagerAdapter(this)
viewPager.adapter = adapter

// BottomNavigationView with NavController
val bottomNav = findViewById<BottomNavigationView>(R.id.bottomNav)
val navController = findNavController(R.id.nav_host_fragment)
bottomNav.setupWithNavController(navController)

// TabLayout with ViewPager2
val tabLayout = findViewById<TabLayout>(R.id.tabLayout)
val viewPager = findViewById<ViewPager2>(R.id.viewPager)
viewPager.adapter = ViewPagerAdapter(this)
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
    tab.text = "Tab ${position + 1}"
}.attach()

Permissions Framework

// Declaring permissions in AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

// Runtime permission checking and requesting
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) 
        != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(
        this,
        arrayOf(Manifest.permission.CAMERA),
        CAMERA_PERMISSION_CODE
    )
}

// Handling permission results
override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<String>,
    grantResults: IntArray
) {
    when (requestCode) {
        CAMERA_PERMISSION_CODE -> {
            if (grantResults.isNotEmpty() && 
                grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission granted, proceed with camera operation
            } else {
                // Permission denied, handle accordingly
            }
            return
        }
    }
}

Data Storage APIs

Storage OptionUse CaseCode Example
SharedPreferencesSmall key-value pairsval prefs = getSharedPreferences("app_prefs", Context.MODE_PRIVATE) <br> prefs.edit().putString("key", "value").apply()
Room DatabaseStructured data, complex queries@Database(entities = [User::class], version = 1) <br> abstract class AppDatabase : RoomDatabase() { ... }
File StorageRaw file data, media filesopenFileOutput("data.txt", Context.MODE_PRIVATE).use { it.write(data.toByteArray()) }
ContentProvidersSharing data between appscontentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, ...)
DataStoreAsynchronous, type-safe preferencesval dataStore = context.createDataStore("settings") <br> val preferenceFlow: Flow<Preferences> = dataStore.data

Networking APIs

// Retrofit setup
interface ApiService {
    @GET("users")
    suspend fun getUsers(): List<User>
}

val retrofit = Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

val apiService = retrofit.create(ApiService::class.java)

// Making network requests with coroutines
lifecycleScope.launch {
    try {
        val users = apiService.getUsers()
        // Process users
    } catch (e: Exception) {
        // Handle error
    }
}

// Using OkHttp interceptors
val client = OkHttpClient.Builder()
    .addInterceptor(HttpLoggingInterceptor().apply {
        level = HttpLoggingInterceptor.Level.BODY
    })
    .addInterceptor { chain ->
        val original = chain.request()
        val request = original.newBuilder()
            .header("Authorization", "Bearer $token")
            .build()
        chain.proceed(request)
    }
    .build()

Android Jetpack Components

ComponentPurposeImplementation
ViewModelUI state holderclass MyViewModel : ViewModel() { ... }
LiveDataObservable dataprivate val _data = MutableLiveData<String>() <br> val data: LiveData<String> = _data
RoomDatabase abstraction@Entity data class User(...) <br> @Dao interface UserDao { ... }
WorkManagerBackground processingval workRequest = OneTimeWorkRequestBuilder<MyWorker>().build() <br> WorkManager.getInstance(context).enqueue(workRequest)
NavigationApp navigationfindNavController().navigate(R.id.action_to_details)
PagingLoad and display dataval flow = Pager(config) { UserPagingSource() }.flow
DataStoreData storageval dataStore = context.createDataStore("settings")
CameraXCamera functionalityval preview = Preview.Builder().build() <br> preview.setSurfaceProvider(previewView.surfaceProvider)
HiltDependency injection@AndroidEntryPoint class MainActivity : AppCompatActivity() { ... }

Media and Graphics

// Loading images with Glide
Glide.with(context)
    .load(imageUrl)
    .placeholder(R.drawable.placeholder)
    .error(R.drawable.error)
    .into(imageView)

// MediaPlayer for audio playback
val mediaPlayer = MediaPlayer.create(context, R.raw.audio_file)
mediaPlayer.start()
mediaPlayer.setOnCompletionListener { mp -> mp.release() }

// ExoPlayer for streaming media
val player = ExoPlayer.Builder(context).build()
val mediaItem = MediaItem.fromUri(videoUrl)
player.setMediaItem(mediaItem)
player.prepare()
player.play()

// Canvas drawing
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
val paint = Paint().apply {
    color = Color.RED
    style = Paint.Style.FILL
}
canvas.drawCircle(centerX, centerY, radius, paint)

Location and Maps

// FusedLocationProvider for location updates
val locationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 10000)
    .setWaitForAccurateLocation(false)
    .setMinUpdateIntervalMillis(5000)
    .build()

val locationCallback = object : LocationCallback() {
    override fun onLocationResult(locationResult: LocationResult) {
        for (location in locationResult.locations) {
            // Process location
        }
    }
}

val client = LocationServices.getFusedLocationProviderClient(this)
client.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())

// Google Maps setup
class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
    private lateinit var mMap: GoogleMap
    
    override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap
        
        // Add a marker in Sydney
        val sydney = LatLng(-34.0, 151.0)
        mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 12f))
    }
}

Notifications

// Create notification channel (Android 8.0+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val channelId = "channel_id"
    val channel = NotificationChannel(
        channelId,
        "Channel Name",
        NotificationManager.IMPORTANCE_DEFAULT
    ).apply {
        description = "Channel Description"
    }
    
    val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    notificationManager.createNotificationChannel(channel)
}

// Build and show notification
val notificationBuilder = NotificationCompat.Builder(this, "channel_id")
    .setSmallIcon(R.drawable.ic_notification)
    .setContentTitle("Notification Title")
    .setContentText("Notification Text")
    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
    .setAutoCancel(true)
    
// Add action button
val intent = Intent(this, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
    this, 0, intent, PendingIntent.FLAG_IMMUTABLE
)
notificationBuilder.setContentIntent(pendingIntent)

// Create expandable notification
notificationBuilder.setStyle(NotificationCompat.BigTextStyle()
    .bigText("This is a longer notification text that will be displayed when the notification is expanded"))

// Show notification
with(NotificationManagerCompat.from(this)) {
    if (ActivityCompat.checkSelfPermission(applicationContext, Manifest.permission.POST_NOTIFICATIONS) 
            == PackageManager.PERMISSION_GRANTED) {
        notify(notificationId, notificationBuilder.build())
    }
}

Testing Tools and APIs

Unit Testing with JUnit and Mockito

// Basic JUnit test
@Test
fun addition_isCorrect() {
    assertEquals(4, 2 + 2)
}

// Testing a ViewModel with Mockito
@RunWith(MockitoJUnitRunner::class)
class UserViewModelTest {
    @Mock
    private lateinit var repository: UserRepository
    
    @Rule
    @JvmField
    val instantExecutorRule = InstantTaskExecutorRule()
    
    private lateinit var viewModel: UserViewModel
    
    @Before
    fun setup() {
        viewModel = UserViewModel(repository)
    }
    
    @Test
    fun `fetchUsers should update LiveData on success`() = runBlockingTest {
        // Given
        val users = listOf(User("John"), User("Jane"))
        `when`(repository.getUsers()).thenReturn(users)
        
        // When
        viewModel.fetchUsers()
        
        // Then
        val value = viewModel.users.getOrAwaitValue()
        assertEquals(users, value)
    }
}

UI Testing with Espresso

// Basic Espresso test
@RunWith(AndroidJUnit4::class)
class MainActivityTest {
    @get:Rule
    val activityRule = ActivityScenarioRule(MainActivity::class.java)
    
    @Test
    fun clickButton_opensNewActivity() {
        // Find the button and perform click
        onView(withId(R.id.button_login))
            .check(matches(isDisplayed()))
            .perform(click())
        
        // Verify new activity is launched with expected text
        onView(withId(R.id.text_welcome))
            .check(matches(withText("Welcome!")))
    }
    
    @Test
    fun enterText_showsInTextField() {
        // Type text in EditText
        onView(withId(R.id.edit_text))
            .perform(typeText("Hello Espresso!"), closeSoftKeyboard())
        
        // Check if text is displayed
        onView(withId(R.id.edit_text))
            .check(matches(withText("Hello Espresso!")))
    }
}

Benchmark Testing

// In app/build.gradle
androidTest {
    targetProjectPath = ":benchmark"
}

// In benchmark module
@RunWith(AndroidJUnit4::class)
class MyBenchmark {
    @get:Rule
    val benchmarkRule = BenchmarkRule()
    
    @Test
    fun benchmarkSomeFunction() {
        val context = ApplicationProvider.getApplicationContext<Context>()
        val packageName = "com.example.myapp"
        
        benchmarkRule.measureRepeated(
            packageName = packageName,
            metrics = listOf(StartupTimingMetric()),
            iterations = 5,
            setupBlock = {
                pressHome()
                startActivityAndWait()
            }
        ) {
            // Code to benchmark
        }
    }
}

Build System and Gradle

Gradle Build Configuration

// build.gradle (Project level)
buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.4.2'
        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10'
        classpath 'com.google.dagger:hilt-android-gradle-plugin:2.44'
    }
}

// build.gradle.kts (Module level)
plugins {
    id("com.android.application")
    id("kotlin-android")
    id("kotlin-kapt")
    id("dagger.hilt.android.plugin")
}

android {
    namespace = "com.example.myapp"
    compileSdk = 33
    
    defaultConfig {
        applicationId = "com.example.myapp"
        minSdk = 24
        targetSdk = 33
        versionCode = 1
        versionName = "1.0.0"
        
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
    
    buildTypes {
        release {
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    
    buildFeatures {
        viewBinding = true
        dataBinding = true
        compose = true
    }
    
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {
    // Core Android dependencies
    implementation("androidx.core:core-ktx:1.10.0")
    implementation("androidx.appcompat:appcompat:1.6.1")
    implementation("com.google.android.material:material:1.9.0")
    
    // Jetpack components
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1")
    implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.1")
    implementation("androidx.room:room-runtime:2.5.1")
    implementation("androidx.room:room-ktx:2.5.1")
    kapt("androidx.room:room-compiler:2.5.1")
    
    // Network libraries
    implementation("com.squareup.retrofit2:retrofit:2.9.0")
    implementation("com.squareup.retrofit2:converter-gson:2.9.0")
    implementation("com.squareup.okhttp3:okhttp:4.10.0")
    implementation("com.squareup.okhttp3:logging-interceptor:4.10.0")
    
    // Image loading
    implementation("com.github.bumptech.glide:glide:4.15.1")
    
    // Testing
    testImplementation("junit:junit:4.13.2")
    testImplementation("org.mockito:mockito-core:5.3.1")
    testImplementation("androidx.arch.core:core-testing:2.2.0")
    androidTestImplementation("androidx.test.ext:junit:1.1.5")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}

Gradle Tasks and Commands

# Basic Gradle commands
./gradlew tasks                     # List available tasks
./gradlew clean                     # Clean build outputs
./gradlew build                     # Build all modules
./gradlew assembleDebug             # Build debug APK
./gradlew assembleRelease           # Build release APK
./gradlew installDebug              # Install debug APK
./gradlew test                      # Run unit tests
./gradlew connectedAndroidTest      # Run instrumented tests

# Dependency analysis
./gradlew app:dependencies          # Show all dependencies
./gradlew app:dependencyUpdates     # Check for updates (requires plugin)

# Custom tasks and automation
./gradlew lint                      # Run lint checks
./gradlew bundleRelease             # Create AAB for Play Store
./gradlew appDistributionUploadRelease  # Upload to Firebase App Distribution

Android App Bundle Configuration

android {
    // ...
    bundle {
        language {
            enableSplit = true
        }
        density {
            enableSplit = true
        }
        abi {
            enableSplit = true
        }
    }
    
    dynamicFeatures = [":feature_one", ":feature_two"]
}

Common Challenges and Solutions

Memory Management

ChallengeSolution
Memory LeaksUse LeakCanary, avoid static contexts, properly dispose subscriptions
OutOfMemoryErrorOptimize bitmap loading, use memory-efficient collections, implement pagination
ANR (Application Not Responding)Move heavy operations to background threads, use coroutines or WorkManager
High memory usageImplement object pooling, use SparseArray for maps with integer keys

Performance Optimization

AreaTechniques
UI PerformanceUse ConstraintLayout, avoid nested layouts, recycle views with RecyclerView
Startup TimeImplement app startup, lazy initialization, deferred components
Battery UsageBatch network calls, use JobScheduler/WorkManager, optimize location updates
Network EfficiencyCache responses, implement offline support, compress data
Database OperationsUse Room with coroutines, batch operations, proper indexing

Security Best Practices

// Secure SharedPreferences with EncryptedSharedPreferences
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)

val sharedPreferences = EncryptedSharedPreferences.create(
    "secret_shared_prefs",
    masterKeyAlias,
    applicationContext,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

// Certificate pinning with OkHttp
val certificatePinner = CertificatePinner.Builder()
    .add("example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
    .build()

val client = OkHttpClient.Builder()
    .certificatePinner(certificatePinner)
    .build()

// Secure file storage
val file = File(context.filesDir, "sensitive_data.txt")
// Use file for internal storage (not accessible by other apps)

// Secure content provider
<provider
    android:name=".MyContentProvider"
    android:authorities="com.example.myapp.provider"
    android:exported="false" />

Best Practices for SDK Usage

SDK Version Management

  • Target the latest API level: Always target the most recent stable API level
  • Set reasonable minSdk: Balance reach and feature set
  • Handle version-specific code: Use if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.X) pattern
  • Use AndroidX: Migrate from Support Library to AndroidX
  • Implement compatibility libraries: Use Jetpack libraries for backward compatibility

Resource Optimization

  • Density-specific drawables: Provide resources for different screen densities
  • Vector drawables: Use when possible to reduce APK size
  • String localization: Separate strings into locale-specific files
  • Configuration qualifiers: Use for different screen sizes, orientations
  • Resource shrinking: Enable in Gradle for release builds

SDK Tool Usage

  • Use Lint: Run regular lint checks to identify potential issues
  • Enable ProGuard/R8: Configure code shrinking and obfuscation
  • Set up CI/CD: Automate builds and testing with GitHub Actions or similar
  • Analyze APK: Use Android Studio’s APK Analyzer to identify size issues
  • Profile your app: Use Android Profiler for CPU, memory, and network analysis

Resources for Further Learning

Official Documentation

Code Samples and Repos

Learning Paths

  • Google Codelabs for Android Development
  • Android Developers YouTube Channel
  • Android Developers Blog
  • Google I/O sessions and recordings
Scroll to Top