COER UNIVERSITY Android App Development – Lab Sheet 6 (Hard
Level Questions)
B. Tech II Semester (Session 2024–2025)
Faculty – Dr. Akshay Juneja
Name: Vishesh Kumar
Roll No: 55
Sec:- D
CUID:- CU24250050
Q1. Demonstrate inline functions with crossinline and noinline
parameters .
Ans:- Explanation:
Inline functions copy the function body at the call site to improve
performance and enable lambda inlining.
Crossinline prevents non-local returns from lambdas, which helps in cases
like forEach or asynchronous callbacks.
Noinline prevents a lambda from being inlined, useful when passing a
lambda to another function.
Code:
Inline fun process(
Crossinline transform: (String) -> String,
Noinline onComplete: () -> Unit
){
Val items = listOf(“One”, “Two”, “Three”)
Items.forEach {
Println(transform(it))
onComplete()
}
Fun main() {
Process(
Transform = { it.reversed() },
onComplete = { println(“All items processed.”) }
Q2. Demonstrate CoroutineScope and structured concurrency
Ans:-
Explanation:
Structured concurrency ensures all child coroutines are scoped properly and
don’t leak memory. runBlocking, launch, and async manage lifecycles
cleanly.
Code:
Import kotlinx.coroutines.*
Fun main() = runBlocking {
Launch {
Repeat(3) {
Delay(500)
Println(“Coroutine running: $it”)
Println(“Main program done.”)
Q3. Implement a custom operator function (invoke).
Ans:-
Explanation:
The invoke() operator allows objects to be called like functions, enabling
function-like syntax.
Code:
Class Greet(val message: String) {
Operator fun invoke(name: String) {
Println(“$message, $name!”)
Fun main() {
Val greet = Greet(“Hello”)
Greet(“Alice”)
Q4. Demonstrate channel-based communication using coroutines.
Ans:-
Explanation:
Channel enables safe communication between coroutines. Send and receive
are used to share data across coroutines.
Code:
Import kotlinx.coroutines.*
Import kotlinx.coroutines.channels.*
Fun main() = runBlocking {
Val channel = Channel<Int>()
Launch {
For (x in 1..5) {
Channel.send(x)
Channel.close()
For (y in channel) {
Println(“Received: $y”)
Q5. Demonstrate tail recursion optimization.
Ans:-
Explanation:
Tail recursion reuses stack frames for recursive functions, preventing stack
overflow. Use tailrec keyword.
Code:
Tailrec fun factorial(n: Int, acc: Long = 1): Long {
Return if (n <= 1) acc else factorial(n – 1, acc * n)
Fun main() {
Println(“Factorial: ${factorial(5)}”)
Q6. Implement a custom delegate using provideDelegate
Ans:-
Explanation:
provideDelegate lets you customize how delegation works when a property is
declared using by keyword.
Code:
Import kotlin.reflect.KProperty
Class DelegateProvider {
Operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>) =
Delegate()
Class Delegate {
Operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
Return “Value for ${property.name}”
Class Example {
Val name by DelegateProvider()
Fun main() {
Val e = Example()
Println(e.name)
Q7. Embed a Kotlin scripting engine using javax.script.ScriptEngine.
Ans:-
Explanation:
ScriptEngine allows dynamic execution of Kotlin code at runtime.
Code:
Import javax.script.ScriptEngineManager
Fun main() {
Val engine = ScriptEngineManager().getEngineByExtension(“kts”)
Val result = engine.eval(“val x = 5; val y = 10; x + y”)
Println(“Script Result: $result”)
Q8. Demonstrate deep copy and shallow copy.
Ans:-
Explanation:
Shallow copy duplicates references, deep copy duplicates full structure.
deepCopy() manually copies nested objects.
Code:
Data class Address(val city: String)
Data class Person(val name: String, val address: Address)
Fun deepCopy(person: Person): Person {
Return person.copy(address = Address(person.address.city))
Fun main() {
Val p1 = Person(“Sam”, Address(“Delhi”))
Val p2 = deepCopy(p1)
Println(p2)
Q9. Use inline functions with generic types.
Ans:-
Explanation:
Using reified with inline lets us access type info at runtime in generic
functions.
Code:
Inline fun <reified T> getTypeName(): String {
Return T::class.simpleName ?: “Unknown”
Fun main() {
Println(getTypeName<String>())
Println(getTypeName<Int>())
Q10. Create a compile-time annotation processor.
Ans:-
Explanation:
Custom annotations are processed during compilation. Requires kapt and
annotation processor setup.
Code:
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE)
Annotation class AutoGenerate
@AutoGenerate
Class MyClass