trustformers-mobile 0.1.1

Mobile deployment support for TrustformeRS (iOS, Android)
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
# Tutorial 3: Android Quick Start with TrustformeRS
**Duration**: 9 minutes  
**Target Audience**: Android developers  
**Prerequisites**: Android Studio, Kotlin knowledge, API 21+

## Video Script

### Opening (0:00 - 0:30)
**[Screen: Android Studio welcome screen]**

**Narrator**: "Welcome to the Android Quick Start tutorial! Today we're building an intelligent Android app using TrustformeRS that performs AI inference completely on-device. We'll use Jetpack Compose for a modern UI and Kotlin coroutines for smooth async operations."

**[Screen: Final app preview on Android device]**

"This is our finished app - a smart text analyzer that works offline with hardware acceleration. Let's build it step by step!"

### Project Setup (0:30 - 2:00)
**[Screen: Android Studio new project dialog]**

**Narrator**: "First, let's create a new Android project. Open Android Studio and select 'Create New Project'. Choose 'Empty Compose Activity' for a modern UI foundation."

**[Screen: Project configuration]**

"I'll name this 'TrustformeRSDemo', set the package name to 'com.example.trustformersdemo', and make sure we're targeting API 21 or higher for broad device compatibility."

**[Screen: Project structure view]**

"Perfect! Our project is created with Jetpack Compose already configured. Now let's add the TrustformeRS dependency."

### Adding TrustformeRS Dependency (2:00 - 3:00)
**[Screen: app/build.gradle.kts file]**

**Narrator**: "Open the app-level build.gradle.kts file and add TrustformeRS to our dependencies section:"

```kotlin
dependencies {
    implementation("com.trustformers:trustformers-android:1.0.0")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
    
    // Existing Compose dependencies...
    implementation("androidx.compose.ui:ui:$compose_version")
    implementation("androidx.compose.ui:ui-tooling-preview:$compose_version")
    implementation("androidx.compose.material3:material3:1.1.2")
    implementation("androidx.activity:activity-compose:1.8.0")
    implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
}
```

**[Screen: Sync project button]**

"Click 'Sync Now' to download the dependencies. This might take a moment."

**[Screen: Sync successful notification]**

"Great! TrustformeRS is now ready to use in our project."

### Setting Up the ViewModel (3:00 - 4:30)
**[Screen: Creating new Kotlin file]**

**Narrator**: "Let's create a ViewModel to manage our AI engine and app state. Right-click on your package and create a new Kotlin file called 'MainViewModel'."

**[Screen: ViewModel code]**

```kotlin
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.trustformers.android.TrustformersEngine
import com.trustformers.android.TrustformersConfig
import com.trustformers.android.Backend
import com.trustformers.android.Quantization
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

class MainViewModel : ViewModel() {
    private val _uiState = MutableStateFlow(UiState())
    val uiState: StateFlow<UiState> = _uiState.asStateFlow()
    
    private var engine: TrustformersEngine? = null
    
    data class UiState(
        val inputText: String = "",
        val outputText: String = "Ready to analyze your text!",
        val isLoading: Boolean = false,
        val isModelLoaded: Boolean = false
    )
    
    init {
        loadModel()
    }
    
    private fun loadModel() {
        viewModelScope.launch {
            try {
                _uiState.value = _uiState.value.copy(
                    isLoading = true,
                    outputText = "Loading AI model..."
                )
                
                val config = TrustformersConfig.Builder()
                    .setModelName("bert-base-uncased")
                    .setQuantization(Quantization.INT8)
                    .setBackend(Backend.NNAPI)
                    .build()
                
                engine = TrustformersEngine.create(config)
                
                _uiState.value = _uiState.value.copy(
                    isLoading = false,
                    isModelLoaded = true,
                    outputText = "Model loaded successfully! Enter text to analyze."
                )
            } catch (e: Exception) {
                _uiState.value = _uiState.value.copy(
                    isLoading = false,
                    outputText = "Error loading model: ${e.message}"
                )
            }
        }
    }
    
    fun updateInputText(text: String) {
        _uiState.value = _uiState.value.copy(inputText = text)
    }
    
    fun analyzeText() {
        val currentText = _uiState.value.inputText
        if (currentText.isBlank() || engine == null) return
        
        viewModelScope.launch {
            try {
                _uiState.value = _uiState.value.copy(isLoading = true)
                
                val result = engine!!.classify(currentText)
                
                _uiState.value = _uiState.value.copy(
                    isLoading = false,
                    outputText = """
                        Classification Results:
                        
                        Label: ${result.label}
                        Confidence: ${"%.2f".format(result.confidence * 100)}%
                        
                        Processing Time: ${result.processingTimeMs}ms
                        Model: ${result.modelInfo.name}
                        Backend: ${result.modelInfo.backend}
                    """.trimIndent()
                )
            } catch (e: Exception) {
                _uiState.value = _uiState.value.copy(
                    isLoading = false,
                    outputText = "Error: ${e.message}"
                )
            }
        }
    }
    
    override fun onCleared() {
        super.onCleared()
        engine?.close()
    }
}
```

### Building the Compose UI (4:30 - 6:30)
**[Screen: MainActivity.kt file]**

**Narrator**: "Now let's build our Compose UI in MainActivity. We'll create a clean, Material 3 design with text input and output areas:"

```kotlin
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TrustformeRSDemo(
    viewModel: MainViewModel = viewModel()
) {
    val uiState by viewModel.uiState.collectAsState()
    
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Text(
            text = "TrustformeRS Android Demo",
            style = MaterialTheme.typography.headlineMedium
        )
        
        OutlinedTextField(
            value = uiState.inputText,
            onValueChange = { viewModel.updateInputText(it) },
            label = { Text("Enter text to analyze") },
            modifier = Modifier
                .fillMaxWidth()
                .height(120.dp),
            maxLines = 4
        )
        
        Button(
            onClick = { viewModel.analyzeText() },
            modifier = Modifier.fillMaxWidth(),
            enabled = !uiState.isLoading && uiState.isModelLoaded && uiState.inputText.isNotBlank()
        ) {
            if (uiState.isLoading) {
                CircularProgressIndicator(
                    modifier = Modifier.size(16.dp),
                    strokeWidth = 2.dp
                )
                Spacer(modifier = Modifier.width(8.dp))
            }
            Text(if (uiState.isLoading) "Analyzing..." else "Analyze Text")
        }
        
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .weight(1f)
        ) {
            Column(
                modifier = Modifier.padding(16.dp)
            ) {
                Text(
                    text = "Results",
                    style = MaterialTheme.typography.titleMedium
                )
                Spacer(modifier = Modifier.height(8.dp))
                Text(
                    text = uiState.outputText,
                    modifier = Modifier
                        .fillMaxWidth()
                        .verticalScroll(rememberScrollState()),
                    style = MaterialTheme.typography.bodyMedium
                )
            }
        }
    }
}
```

**[Screen: MainActivity class update]**

"And let's update our MainActivity to use this composable:"

```kotlin
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MaterialTheme {
                TrustformeRSDemo()
            }
        }
    }
}
```

### Adding Permissions (6:30 - 7:00)
**[Screen: AndroidManifest.xml]**

**Narrator**: "TrustformeRS might need internet permission for initial model downloads. Let's add it to our AndroidManifest.xml:"

```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    
    <uses-permission android:name="android.permission.INTERNET" />
    
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.TrustformeRSDemo">
        
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:theme="@style/Theme.TrustformeRSDemo">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
    </application>
</manifest>
```

### Testing the App (7:00 - 8:30)
**[Screen: Android device/emulator selection]**

**Narrator**: "Time to test our app! I'll run it on an Android emulator first. Make sure you have an AVD with API 21 or higher."

**[Screen: App compilation and installation]**

"The app is building and installing. This first launch might take a bit longer as TrustformeRS downloads and caches the AI model."

**[Screen: App running on emulator]**

"Great! The app is loading the BERT model. You can see the loading indicator and status message."

**[Screen: Text input demonstration]**

"Now the model is loaded. Let me enter some text: 'I absolutely love this new Android app!' and tap 'Analyze Text'."

**[Screen: Results display]**

"Excellent! The model classified this as positive sentiment with 92% confidence, and it only took 31 milliseconds. That's incredibly fast for on-device processing!"

**[Screen: Testing on physical device]**

"Let me also test this on a real Android device to show you the performance with hardware acceleration..."

### Performance and Next Steps (8:30 - 9:00)
**[Screen: Performance comparison chart]**

**Narrator**: "Notice how much faster this runs on a real device with NNAPI acceleration. TrustformeRS automatically chooses the best backend for your hardware."

**[Screen: Feature highlights]**

"What makes this special? We're using INT8 quantization for efficiency, NNAPI for hardware acceleration, and everything runs completely offline. Your users' data never leaves their device."

**[Screen: Next tutorial preview]**

"In our next tutorial, we'll explore performance optimization techniques, including GPU acceleration and advanced quantization strategies. Don't forget to subscribe and I'll see you next time!"

## Supporting Materials

### Complete Project Files

#### build.gradle.kts (app)
```kotlin
dependencies {
    implementation("com.trustformers:trustformers-android:1.0.0")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
    
    implementation("androidx.core:core-ktx:1.12.0")
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
    implementation("androidx.activity:activity-compose:1.8.0")
    implementation("androidx.compose.ui:ui:$compose_version")
    implementation("androidx.compose.ui:ui-tooling-preview:$compose_version")
    implementation("androidx.compose.material3:material3:1.1.2")
    implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
    
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.1.5")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
    androidTestImplementation("androidx.compose.ui:ui-test-junit4:$compose_version")
    debugImplementation("androidx.compose.ui:ui-tooling:$compose_version")
}
```

#### MainViewModel.kt (Complete)
[See above in video script]

#### MainActivity.kt (Complete)
```kotlin
package com.example.trustformersdemo

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.trustformersdemo.ui.theme.TrustformeRSDemoTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            TrustformeRSDemoTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    TrustformeRSDemo()
                }
            }
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TrustformeRSDemo(
    viewModel: MainViewModel = viewModel()
) {
    val uiState by viewModel.uiState.collectAsState()
    
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Text(
            text = "TrustformeRS Android Demo",
            style = MaterialTheme.typography.headlineMedium
        )
        
        OutlinedTextField(
            value = uiState.inputText,
            onValueChange = { viewModel.updateInputText(it) },
            label = { Text("Enter text to analyze") },
            modifier = Modifier
                .fillMaxWidth()
                .height(120.dp),
            maxLines = 4
        )
        
        Button(
            onClick = { viewModel.analyzeText() },
            modifier = Modifier.fillMaxWidth(),
            enabled = !uiState.isLoading && uiState.isModelLoaded && uiState.inputText.isNotBlank()
        ) {
            if (uiState.isLoading) {
                CircularProgressIndicator(
                    modifier = Modifier.size(16.dp),
                    strokeWidth = 2.dp
                )
                Spacer(modifier = Modifier.width(8.dp))
            }
            Text(if (uiState.isLoading) "Analyzing..." else "Analyze Text")
        }
        
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .weight(1f)
        ) {
            Column(
                modifier = Modifier.padding(16.dp)
            ) {
                Text(
                    text = "Results",
                    style = MaterialTheme.typography.titleMedium
                )
                Spacer(modifier = Modifier.height(8.dp))
                Text(
                    text = uiState.outputText,
                    modifier = Modifier
                        .fillMaxWidth()
                        .verticalScroll(rememberScrollState()),
                    style = MaterialTheme.typography.bodyMedium
                )
            }
        }
    }
}
```

### Demo Text Examples
1. **Positive**: "I absolutely love this new Android app!"
2. **Negative**: "This experience was frustrating and disappointing."
3. **Neutral**: "The Android documentation explains the API."
4. **Technical**: "Kotlin coroutines provide asynchronous programming."
5. **Mixed**: "While the UI is beautiful, the performance could be better."

### Key Teaching Points
1. **Kotlin coroutines** with viewModelScope
2. **Jetpack Compose** state management
3. **StateFlow and collectAsState** patterns
4. **Material 3** design components
5. **MVVM architecture** with ViewModel
6. **Resource cleanup** with onCleared()

### Performance Optimization Tips
- Use NNAPI backend for hardware acceleration
- Enable INT8 quantization for memory efficiency
- Test on real devices for accurate performance metrics
- Monitor memory usage with Android Profiler
- Consider model size vs accuracy trade-offs
- Use background threads for model operations

### Troubleshooting Guide
- **Model loading slow**: Normal on first load, cached afterwards
- **OutOfMemoryError**: Use quantization or smaller models
- **Backend not available**: Falls back to CPU automatically
- **Permissions**: Internet only needed for initial model download
- **Emulator performance**: Much slower than real devices
- **Coroutine errors**: Ensure proper scope management