Bỏ qua để đến nội dung

Android Framework

Phần này tổng hợp các câu hỏi phỏng vấn phổ biến về Android Framework, dựa trên sách Manifest Android Interview của Jaewoong Eum.


Q: Context trong Android là gì? Có những loại Context nào?

Phần tiêu đề “Q: Context trong Android là gì? Có những loại Context nào?”

Trả lời:

Context là abstract class cung cấp access đến application resources, system services, và các operations như launching activities, broadcasting, receiving intents.

Các loại Context:

Loại Mô tả Use Case
Application Context Singleton, tồn tại suốt vòng đời app Singletons, libraries initialization
Activity Context Gắn với lifecycle của Activity UI operations, dialogs, themes
Service Context Gắn với lifecycle của Service Background operations
Base Context Context nền tảng của ContextWrapper Custom ContextWrapper
// Application Context - an toàn cho long-lived objects
val appContext = applicationContext
// Activity Context - cho UI operations
val dialog = AlertDialog.Builder(this) // 'this' là Activity
.setTitle("Example")
.show()

⚠️ Quan trọng: Sử dụng applicationContext cho objects tồn tại lâu dài để tránh memory leak. Chỉ dùng Activity context cho UI operations.

📚 Tìm hiểu thêm: Activity trong Android


Q: Sự khác nhau giữa thisbaseContext trong Activity?

Phần tiêu đề “Q: Sự khác nhau giữa this và baseContext trong Activity?”

Trả lời:

  • this: Reference đến instance Activity hiện tại, bao gồm lifecycle và UI capabilities
  • baseContext: Context nền tảng mà Activity được xây dựng trên đó (từ ContextWrapper)
// this - cho UI operations
val intent = Intent(this, DetailActivity::class.java)
startActivity(intent)
// baseContext - cho custom ContextWrapper
override fun attachBaseContext(newBase: Context) {
super.attachBaseContext(CustomContextWrapper(newBase))
}

Khi nào dùng:

  • this: Starting activities, showing dialogs, accessing resources
  • baseContext: Custom theming, locale changes, advanced wrapping

Q: Application class là gì và khi nào nên sử dụng?

Phần tiêu đề “Q: Application class là gì và khi nào nên sử dụng?”

Trả lời:

Application class là base class duy trì global application state, được khởi tạo trước mọi components khác (Activities, Services, BroadcastReceivers).

Các methods quan trọng:

Method Mô tả
onCreate() Khởi tạo app-wide dependencies, chỉ gọi 1 lần
onTerminate() Chỉ gọi trong emulator, không dùng production
onLowMemory() Hệ thống thiếu memory
onTrimMemory() Memory state thay đổi, granular control
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// Initialize global dependencies
initTimber()
initAnalytics()
initDependencyInjection()
}
private fun initTimber() {
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
}
}
}
AndroidManifest.xml
<application
android:name=".MyApplication"
... >
</application>

Best Practices:

  • ✅ Initialize libraries (Timber, Firebase, Analytics)
  • ✅ Setup dependency injection (Hilt, Koin)
  • ❌ Avoid long-running tasks trong onCreate()
  • ❌ Don’t store Activity references

Q: Mục đích của file AndroidManifest.xml là gì?

Phần tiêu đề “Q: Mục đích của file AndroidManifest.xml là gì?”

Trả lời:

AndroidManifest.xml là file cấu hình bắt buộc, cung cấp thông tin về app cho Android OS:

  1. Khai báo Components:

    • Activities, Services, BroadcastReceivers, ContentProviders
  2. Permissions:

    • Quyền app cần (INTERNET, CAMERA, LOCATION)
    • Quyền app cung cấp cho apps khác
  3. Hardware/Software Features:

    • Yêu cầu camera, GPS, sensors
  4. App Metadata:

    • Package name, version, icon, theme
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<!-- Permissions -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<!-- Hardware features -->
<uses-feature android:name="android.hardware.camera"
android:required="false"/>
<application
android:name=".MyApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<!-- Activities -->
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Services -->
<service android:name=".MyService"/>
</application>
</manifest>

📚 Tìm hiểu thêm: AndroidManifest.xml


Q: Có bao nhiêu loại Android Components chính?

Phần tiêu đề “Q: Có bao nhiêu loại Android Components chính?”

Trả lời:

4 loại Android Components:

Component Mô tả Use Case
Activity Màn hình UI, entry point cho user interaction Login screen, Home screen
Service Background tasks không có UI Music playback, sync data
BroadcastReceiver Nhận và xử lý system/app events Battery low, network change
ContentProvider Chia sẻ data giữa các apps Contacts, Media files
// Activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
// Service
class MusicService : Service() {
override fun onBind(intent: Intent?): IBinder? = null
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// Play music in background
return START_STICKY
}
}
// BroadcastReceiver
class NetworkReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// Handle network change
}
}

📚 Tìm hiểu thêm: Services trong Android


Trả lời:

Aspect Activity Fragment
Definition Full-screen component Reusable UI portion
Lifecycle Independent Depends on host Activity
Back Stack Activity stack Fragment back stack
Communication Intents ViewModel, interfaces
Resource Heavyweight Lightweight

Khi nào dùng Fragment:

  • ✅ Multi-pane layouts (tablet)
  • ✅ Reusable UI components
  • ✅ Navigation với Navigation Component
  • ✅ Bottom navigation, tabs
// Adding Fragment
supportFragmentManager.beginTransaction()
.replace(R.id.container, HomeFragment())
.addToBackStack(null)
.commit()

📚 Tìm hiểu thêm: Fragments


Q: Điều gì xảy ra khi configuration change (xoay màn hình)?

Phần tiêu đề “Q: Điều gì xảy ra khi configuration change (xoay màn hình)?”

Trả lời:

Khi configuration change xảy ra (screen rotation, language change, keyboard availability), mặc định:

  1. onPause()onStop()onSaveInstanceState()onDestroy()
  2. onCreate()onStart()onRestoreInstanceState()onResume()

Các cách xử lý:

class MainViewModel : ViewModel() {
private val _data = MutableLiveData<List<Item>>()
val data: LiveData<List<Item>> = _data
// Data survives configuration changes
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("key", value)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
savedInstanceState?.getString("key")?.let { value = it }
}
@Composable
fun Counter() {
var count by rememberSaveable { mutableStateOf(0) }
Button(onClick = { count++ }) {
Text("Count: $count")
}
}
<activity android:name=".MainActivity"
android:configChanges="orientation|screenSize"/>

📚 Tìm hiểu thêm: ViewModel, Compose State


Q: Android quản lý memory như thế nào? Làm sao tránh memory leaks?

Phần tiêu đề “Q: Android quản lý memory như thế nào? Làm sao tránh memory leaks?”

Trả lời:

Android sử dụng Garbage Collection tự động thu hồi memory không sử dụng. Khi memory thấp, Low Memory Killer sẽ terminate background processes.

Nguyên nhân Memory Leaks:

Nguyên nhân Giải pháp
Static reference to Context Dùng applicationContext
Long-lived listeners Unregister trong onDestroy()
Inner class giữ outer reference Dùng WeakReference hoặc static class
Handler/Runnable Remove callbacks trong onDestroy()

Best Practices:

// ❌ Memory leak - static reference to Activity
companion object {
var activity: Activity? = null // DON'T DO THIS
}
// ✅ Use WeakReference
class MyHandler(activity: Activity) : Handler(Looper.getMainLooper()) {
private val activityRef = WeakReference(activity)
override fun handleMessage(msg: Message) {
activityRef.get()?.let { activity ->
// Safe to use
}
}
}
// ✅ Use lifecycle-aware components
viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.data.collect { updateUI(it) }
}
}

Tools phát hiện leaks:

  • LeakCanary
  • Android Studio Memory Profiler

Q: ANR là gì? Nguyên nhân và cách phòng tránh?

Phần tiêu đề “Q: ANR là gì? Nguyên nhân và cách phòng tránh?”

Trả lời:

ANR xảy ra khi Main Thread bị block hơn 5 giây, khiến app không phản hồi.

Nguyên nhân:

  • Heavy computation trên Main Thread
  • Synchronous network/database operations
  • Blocking I/O operations
  • Long loops, Thread.sleep()

Cách phòng tránh:

// ❌ ANR - Network trên Main Thread
val data = api.fetchData() // Blocks UI
// ✅ Use Coroutines
viewModelScope.launch {
val data = withContext(Dispatchers.IO) {
api.fetchData()
}
updateUI(data)
}
// ✅ Use WorkManager for persistent tasks
val request = OneTimeWorkRequestBuilder<SyncWorker>().build()
WorkManager.getInstance(context).enqueue(request)

Tools monitoring:

  • Android Studio Profiler
  • StrictMode
  • ANR traces in /data/anr/

📚 Tìm hiểu thêm: Coroutines, WorkManager


Trả lời:

Type Mô tả Use Case
Explicit Chỉ định component cụ thể Navigate trong app
Implicit Khai báo action, system chọn Share, open URL
// Explicit Intent - navigate to specific Activity
val intent = Intent(this, DetailActivity::class.java).apply {
putExtra("item_id", 123)
}
startActivity(intent)
// Implicit Intent - let system choose handler
val shareIntent = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, "Check this out!")
}
startActivity(Intent.createChooser(shareIntent, "Share via"))
// Open URL
val webIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://google.com"))
startActivity(webIntent)

📚 Tìm hiểu thêm: Intents trong Android


Trả lời:

Storage Use Case Persist Shared
SharedPreferences Simple key-value settings
DataStore Modern replacement for SharedPreferences
Room Database Structured data, complex queries
Internal Storage Private files
External Storage Public files (photos, downloads)
Network/Cloud Remote data synchronization
// DataStore (Recommended)
val dataStore = context.createDataStore("settings")
dataStore.edit { prefs ->
prefs[THEME_KEY] = "dark"
}
// Room Database
@Dao
interface UserDao {
@Query("SELECT * FROM users")
fun getAll(): Flow<List<User>>
@Insert
suspend fun insert(user: User)
}

📚 Tìm hiểu thêm: DataStore, Room Database, SharedPreferences


Q: targetSdk trong build.gradle.kts là gì? Khác gì với minSdkcompileSdk?

Phần tiêu đề “Q: targetSdk trong build.gradle.kts là gì? Khác gì với minSdk và compileSdk?”

Trả lời:

targetSdk là API level mà app được thiết kế và đã test để chạy. Nó cho biết app hỗ trợ đầy đủ các behaviors và features của Android version đó.

build.gradle.kts
android {
namespace = "com.example.app"
compileSdk = 35 // API level để compile code
defaultConfig {
applicationId = "com.example.app"
minSdk = 24 // Android 7.0 - version thấp nhất hỗ trợ
targetSdk = 35 // Android 15 - version app được tối ưu cho
versionCode = 1
versionName = "1.0"
}
}

So sánh 3 loại SDK:

Property Ý nghĩa Ảnh hưởng
minSdk Android version thấp nhất app có thể cài Quyết định tập user có thể sử dụng app
compileSdk API level để compile code Cho phép sử dụng APIs mới nhất khi coding
targetSdk API level app đã test và tối ưu Quyết định behaviors của app trên devices mới

1. Android Behaviors thay đổi theo targetSdk:

// Nếu targetSdk >= 31 (Android 12)
// - Phải khai báo android:exported cho Activities
// - Approximate location permission xuất hiện
// - PendingIntent yêu cầu mutability flag
// Nếu targetSdk >= 33 (Android 13)
// - POST_NOTIFICATIONS permission bắt buộc request runtime
// - Photo picker thay thế storage permissions
// Ví dụ: Request notification permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1)
}

2. Forward Compatibility:

Khi device chạy Android cao hơn targetSdk, hệ thống sẽ chạy compatibility mode để đảm bảo app hoạt động như cũ:

// App với targetSdk = 30 chạy trên Android 14:
// - Không bị ảnh hưởng bởi các restrictions mới của Android 14
// - System "giả lập" behavior của Android 11 cho app

3. Google Play Store Requirements:

// Yêu cầu hiện tại của Google Play:
// - New apps: targetSdk phải >= 34 (Android 14)
// - App updates: targetSdk phải >= 34
// Nếu không cập nhật targetSdk:
// - App bị ẩn khỏi users có device mới
// - App có thể bị xóa khỏi Play Store
// targetSdk = 22: Tất cả permissions cấp lúc install
// targetSdk >= 23: Runtime permissions
fun checkCameraPermission() {
// Với targetSdk >= 23, phải request runtime
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.CAMERA),
CAMERA_REQUEST_CODE
)
} else {
openCamera()
}
}
✅ Nên làm ❌ Tránh
Giữ targetSdk cập nhật để tận dụng features mới Để targetSdk quá cũ gây compatibility issues
Test kỹ trên API level = targetSdk Nâng targetSdk mà không test
Đọc Android Migration Guides khi nâng version Bỏ qua behavior changes documentation
Sử dụng AndroidX compatibility libraries Hard-code version checks

⚠️ Quan trọng: Khi nâng targetSdk, đọc kỹ Behavior Changes của version mới. Mỗi Android version có breaking changes khác nhau.


  1. Trả lời có cấu trúc: Definition → Explanation → Example → Best Practice
  2. Luôn cho ví dụ code khi có thể
  3. Đề cập trade-offs và khi nào không nên dùng
  4. Kết nối với kinh nghiệm thực tế nếu có
  5. Nếu không biết: “I’m not sure, but I would approach it by…”