diff --git a/mirai-api/build.gradle b/mirai-api/build.gradle
index b6f9cceb8..f670aac2b 100644
--- a/mirai-api/build.gradle
+++ b/mirai-api/build.gradle
@@ -2,6 +2,7 @@ apply plugin: "kotlin"
 apply plugin: "java"
 
 dependencies {
-    implementation project(':mirai-core')
+    api project(":mirai-core")
+    runtime files("../../mirai-core/build/classes/kotlin/jvm/main") // mpp targeting android limitation
     implementation project(':mirai-console')
 }
diff --git a/mirai-console/build.gradle b/mirai-console/build.gradle
index 19daa8a75..9d486d9bf 100644
--- a/mirai-console/build.gradle
+++ b/mirai-console/build.gradle
@@ -2,5 +2,6 @@ apply plugin: "kotlin"
 apply plugin: "java"
 
 dependencies {
-    implementation project(':mirai-core')
+    api project(":mirai-core")
+    runtime files("../../mirai-core/build/classes/kotlin/jvm/main") // mpp targeting android limitation
 }
diff --git a/mirai-core/build.gradle.kts b/mirai-core/build.gradle.kts
index addf312ea..d6301572e 100644
--- a/mirai-core/build.gradle.kts
+++ b/mirai-core/build.gradle.kts
@@ -1,7 +1,9 @@
+import com.android.build.gradle.api.AndroidSourceSet
+
 plugins {
     id("kotlinx-atomicfu")
     kotlin("multiplatform")
-    //id("com.android.library")
+    id("com.android.library")
     //id("kotlin-android-extensions")
 }
 
@@ -13,76 +15,75 @@ val coroutinesIoVersion = rootProject.ext["coroutinesio_version"].toString()
 
 val klockVersion = rootProject.ext["klock_version"].toString()
 val ktorVersion = rootProject.ext["ktor_version"].toString()
-/*
-//apply()
-android {
-    compileSdkVersion(29)
-    buildToolsVersion("29.0.2")
-    defaultConfig {
-        applicationId = "com.youngfeng.kotlindsl"
-        minSdkVersion(15)
-        targetSdkVersion(27)
-        versionCode = 1
-        versionName = "1.0"
-        //  testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
-    }
 
-    buildTypes {
-        getByName("release") {
-            isMinifyEnabled = true
-            //proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
+kotlin {
+    android("android") {
+        project.plugins.apply("com.android.library")
+
+        project.android {
+            compileSdkVersion(29)
+            buildToolsVersion("29.0.2")
+            defaultConfig {
+                minSdkVersion(15)
+                targetSdkVersion(29)
+                versionCode = 1
+                versionName = "1.0"
+                //  testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
+            }
+
+            buildTypes {
+                getByName("release") {
+                    isMinifyEnabled = false
+                    //proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
+                }
+            }
+
+            sourceSets.filterIsInstance(com.android.build.gradle.api.AndroidSourceSet::class.java).forEach {
+                it.manifest.srcFile("src/androidMain/res/AndroidManifest.xml")
+                it.res.srcDirs(file("src/androidMain/res"))
+            }
+
+            (sourceSets["main"] as AndroidSourceSet).java.srcDirs(file("src/androidMain/kotlin"))
         }
     }
-
-    sourceSets.forEach {
-        println(it)
-       // it.languageSettings.enableLanguageFeature("InlineClasses")
-    }
-}
-*/
-kotlin {
-    // android("android")
     jvm("jvm")
 
-    sourceSets["commonMain"].apply {
+    val commonMain = sourceSets["commonMain"].apply {
         dependencies {
-
-            implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion")
-
+            api("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion")
             implementation("com.soywiz.korlibs.klock:klock:$klockVersion")
 
-            api("io.ktor:ktor-client-core:$ktorVersion")
-            api("io.ktor:ktor-network:$ktorVersion")
-            api("io.ktor:ktor-http:$ktorVersion")
-
-        }
-    }
-
-    /*
-    sourceSets["androidMain"].apply {
-        dependencies {
-            implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion")
-
-            implementation("io.ktor:ktor-http:$ktorVersion")
-            implementation("io.ktor:ktor-client-core:$ktorVersion")
-            implementation("io.ktor:ktor-client-android:$ktorVersion")
-
-        }
-        languageSettings.enableLanguageFeature("InlineClasses")
-    }*/
-
-    sourceSets["jvmMain"].apply {
-        dependencies {
-            implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
-            implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7")
-
-            implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion")
-
             implementation("io.ktor:ktor-http-cio:$ktorVersion")
             implementation("io.ktor:ktor-http:$ktorVersion")
             implementation("io.ktor:ktor-client-core-jvm:$ktorVersion")
             implementation("io.ktor:ktor-client-cio:$ktorVersion")
 
+            implementation("io.ktor:ktor-client-core:$ktorVersion")
+            implementation("io.ktor:ktor-network:$ktorVersion")
+        }
+    }
+
+    sourceSets["androidMain"].apply {
+        dependencies {
+            dependsOn(commonMain)
+            implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion")
+
+            implementation("io.ktor:ktor-client-android:$ktorVersion")
+
+        }
+        languageSettings.enableLanguageFeature("InlineClasses")
+    }
+
+    sourceSets["jvmMain"].apply {
+        dependencies {
+            dependsOn(commonMain)
+            implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
+            implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7")
+
+            implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion")
+
+            implementation("io.ktor:ktor-client-core-jvm:$ktorVersion")
+
         }
     }
 
@@ -90,10 +91,10 @@ kotlin {
         kotlin.setSrcDirs(listOf("src/$name/kotlin"))
     }
 
-    sourceSets.forEach {
-        it.languageSettings.enableLanguageFeature("InlineClasses")
+    sourceSets.all {
+        languageSettings.enableLanguageFeature("InlineClasses")
 
-        it.dependencies {
+        dependencies {
             implementation("org.jetbrains.kotlin:kotlin-stdlib")
             implementation("org.jetbrains.kotlinx:atomicfu:$atomicFuVersion")
             implementation("org.jetbrains.kotlinx:kotlinx-io:$kotlinXIoVersion")
diff --git a/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/PlatformLogger.kt b/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/PlatformLogger.kt
index fd185a6c1..d94b3aa9d 100644
--- a/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/PlatformLogger.kt
+++ b/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/PlatformLogger.kt
@@ -8,7 +8,7 @@ actual typealias PlatformLogger = AndroidLogger
  * Android 平台的默认的日志记录器, 使用 [Log]
  * 不应该直接构造这个类的实例. 需使用 [DefaultLogger]
  */
-open class AndroidLogger internal constructor(override val identity: String?) : MiraiLoggerPlatformBase() {
+open class AndroidLogger(override val identity: String?) : MiraiLoggerPlatformBase() {
     override fun verbose0(any: Any?) {
         Log.v(identity, any.toString())
     }
diff --git a/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/SolveCaptchaAndroid.kt b/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/SolveCaptchaAndroid.kt
index 5d9459f97..e3cf02d95 100644
--- a/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/SolveCaptchaAndroid.kt
+++ b/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/SolveCaptchaAndroid.kt
@@ -2,11 +2,6 @@ package net.mamoe.mirai.utils
 
 import kotlinx.io.core.IoBuffer
 
-/**
- * 让用户处理验证码
- *
- * @return 用户输入得到的验证码. 非 null 时一定 `length==4`.
- */
 internal actual suspend fun solveCaptcha(captchaBuffer: IoBuffer): String? {
     TODO("Unsupported yet")
 }
\ No newline at end of file
diff --git a/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/io/PlatformDatagramChannelAndroid.kt b/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/io/PlatformDatagramChannelAndroid.kt
index 21ea67377..8669dfcf3 100644
--- a/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/io/PlatformDatagramChannelAndroid.kt
+++ b/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/io/PlatformDatagramChannelAndroid.kt
@@ -9,9 +9,6 @@ import java.net.InetSocketAddress
 import java.nio.channels.DatagramChannel
 import java.nio.channels.ReadableByteChannel
 
-/**
- * 多平台适配的 DatagramChannel.
- */
 actual class PlatformDatagramChannel actual constructor(serverHost: String, serverPort: Short) : Closeable {
     private val serverAddress: InetSocketAddress = InetSocketAddress(serverHost, serverPort.toInt())
     private val channel: DatagramChannel = DatagramChannel.open().connect(serverAddress)
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/MiraiLogger.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/MiraiLogger.kt
index b0db9990b..3633d05bc 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/MiraiLogger.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/MiraiLogger.kt
@@ -141,6 +141,25 @@ object Silent : PlatformLogger() {
     }
 }
 
+@Suppress("FunctionName")
+fun SimpleLogger(logger: (String?, Throwable?) -> Unit): SimpleLogger = SimpleLogger(null, logger)
+
+/**
+ * 简易日志记录, 所有类型日志都会被重定向 [logger]
+ */
+class SimpleLogger(override val identity: String?, private val logger: (String?, Throwable?) -> Unit) : MiraiLoggerPlatformBase() {
+    override fun verbose0(any: Any?) = logger(any?.toString(), null)
+    override fun verbose0(message: String?, e: Throwable?) = logger(message, e)
+    override fun debug0(any: Any?) = logger(any?.toString(), null)
+    override fun debug0(message: String?, e: Throwable?) = logger(message, e)
+    override fun info0(any: Any?) = logger(any?.toString(), null)
+    override fun info0(message: String?, e: Throwable?) = logger(message, e)
+    override fun warning0(any: Any?) = logger(any?.toString(), null)
+    override fun warning0(message: String?, e: Throwable?) = logger(message, e)
+    override fun error0(any: Any?) = logger(any?.toString(), null)
+    override fun error0(message: String?, e: Throwable?) = logger(message, e)
+}
+
 /**
  * 平台基类.
  * 实现了 [follower] 的调用传递.
diff --git a/mirai-debug/src/main/java/PacketDebuger.kt b/mirai-debug/src/main/java/PacketDebuger.kt
index 1c1aef16e..f95e40420 100644
--- a/mirai-debug/src/main/java/PacketDebuger.kt
+++ b/mirai-debug/src/main/java/PacketDebuger.kt
@@ -11,11 +11,6 @@ import kotlinx.io.core.readBytes
 import kotlinx.io.core.readUInt
 import net.mamoe.mirai.message.internal.readMessageChain
 import net.mamoe.mirai.network.protocol.tim.TIMProtocol
-import net.mamoe.mirai.network.protocol.tim.packet.ServerPacket
-import net.mamoe.mirai.network.protocol.tim.packet.UnknownServerPacket
-import net.mamoe.mirai.network.protocol.tim.packet.event.ServerEventPacket
-import net.mamoe.mirai.network.protocol.tim.packet.event.UnknownServerEventPacket
-import net.mamoe.mirai.network.protocol.tim.packet.idHexString
 import net.mamoe.mirai.utils.DecryptionFailedException
 import net.mamoe.mirai.utils.decryptBy
 import net.mamoe.mirai.utils.io.*
@@ -98,7 +93,7 @@ object Main {
                 val decrypted = remaining.decryptBy(sessionKey)
                 println("解密body=${decrypted.toUHexString()}")
 
-                packetReceived(data.read { parseServerPacket(data.size) })
+                packetReceived(data.read { parseServerPacket(data.size, sessionKey) })
             } catch (e: DecryptionFailedException) {
                 println("密文body=" + remaining.toUHexString())
                 println("解密body=解密失败")
diff --git a/mirai-demos/mirai-demo-1/build.gradle b/mirai-demos/mirai-demo-1/build.gradle
index e0a26eb75..51440e243 100644
--- a/mirai-demos/mirai-demo-1/build.gradle
+++ b/mirai-demos/mirai-demo-1/build.gradle
@@ -2,7 +2,8 @@ apply plugin: "kotlin"
 apply plugin: "java"
 
 dependencies {
-    compile project(":mirai-core")
+    api project(":mirai-core")
+    runtime files("../../mirai-core/build/classes/kotlin/jvm/main") // mpp targeting android limitation
     api group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: kotlin_version
     api group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: coroutines_version
 }
diff --git a/mirai-demos/mirai-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt b/mirai-demos/mirai-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt
index af1418edd..80041bd31 100644
--- a/mirai-demos/mirai-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt
+++ b/mirai-demos/mirai-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt
@@ -11,15 +11,8 @@ import net.mamoe.mirai.event.*
 import net.mamoe.mirai.event.events.FriendMessageEvent
 import net.mamoe.mirai.login
 import net.mamoe.mirai.message.*
-import net.mamoe.mirai.network.protocol.tim.packet.OutgoingRawPacket
-import net.mamoe.mirai.network.protocol.tim.packet.PacketId
 import net.mamoe.mirai.network.protocol.tim.packet.action.uploadImage
 import net.mamoe.mirai.network.protocol.tim.packet.login.ifFail
-import net.mamoe.mirai.network.session
-import net.mamoe.mirai.qqAccount
-import net.mamoe.mirai.utils.io.hexToBytes
-import net.mamoe.mirai.utils.io.toByteArray
-import net.mamoe.mirai.utils.io.toUHexString
 import net.mamoe.mirai.utils.suspendToExternalImage
 import java.io.File
 import kotlin.system.exitProcess
@@ -222,21 +215,6 @@ suspend fun directlySubscribe(bot: Bot) {
 
             "发群消息" in it.message -> 580266363u.group().sendMessage(it.message.toString().substringAfter("发群消息"))
 
-            "直接发送包" in it.message -> {
-                val d =
-                    ("01 " + 1994701021u.toByteArray().toUHexString() + " 3E 03 3F A2 00 00 02 BB 00 0A 00 01 00 01 00 5E 4F 53 52 6F 6F 74 3A 43 3A 5C 55 73 65 72 73 5C 48 69 6D 31 38 5C 44 6F 63 75 6D 65 6E 74 73 5C 54 65 6E 63 65 6E 74 20 46 69 6C 65 73 5C 31 30 34 30 34 30 30 32 39 30 5C 49 6D 61 67 65 5C 43 32 43 5C 7B 47 47 42 7E 49 31 5A 4D 43 28 25 49 4D 5A 5F 47 55 51 36 35 5D 51 2E 6A 70 67 00 00 04 7D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 35 02")
-                        .hexToBytes()
-                it.bot.network.socket.sendPacket(
-                    OutgoingRawPacket(
-                        PacketId(0x01_BDu),
-                        it.bot.qqAccount,
-                        "00 00 00 01 2E 01 00 00 69 35".hexToBytes(),
-                        it.bot.network.session.sessionKey,
-                        d
-                    )
-                )
-            }
-
             "上传群图片" in it.message -> withTimeoutOrNull(5000) {
                 val filename = it.message.toString().substringAfter("上传群图片")
                 val image = File(
diff --git a/mirai-demos/mirai-demo-android/build.gradle b/mirai-demos/mirai-demo-android/build.gradle
new file mode 100644
index 000000000..2cc82b84b
--- /dev/null
+++ b/mirai-demos/mirai-demo-android/build.gradle
@@ -0,0 +1,62 @@
+plugins {
+    id 'com.android.application'
+    id 'org.jetbrains.kotlin.multiplatform'
+}
+
+android {
+    compileSdkVersion 29
+    defaultConfig {
+        applicationId "net.mamoe.mirai.demo"
+        minSdkVersion 23
+        targetSdkVersion 29
+        versionCode 1
+        versionName "1.0"
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+    }
+    buildTypes {
+        release {
+            minifyEnabled true
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+    packagingOptions {
+        exclude 'META-INF/main.kotlin_module'
+        exclude 'META-INF/ktor-http.kotlin_module'
+        exclude 'META-INF/kotlinx-io.kotlin_module'
+        exclude 'META-INF/atomicfu.kotlin_module'
+        exclude 'META-INF/ktor-utils.kotlin_module'
+        exclude 'META-INF/kotlinx-coroutines-io.kotlin_module'
+        exclude 'META-INF/kotlinx-coroutines-core.kotlin_module'
+        exclude 'META-INF/ktor-http-cio.kotlin_module'
+        exclude 'META-INF/ktor-http-cio.kotlin_module'
+        exclude 'META-INF/ktor-client-core.kotlin_module'
+    }
+}
+
+kotlin {
+    targets.fromPreset(presets.android, 'android')
+}
+
+dependencies {
+    implementation "org.jetbrains.kotlin:kotlin-stdlib"
+    implementation project(':mirai-core')
+
+    implementation group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: kotlin_version
+    implementation group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: coroutines_version
+    implementation group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-android', version: "1.3.2"
+
+    //implementation 'com.android.support:appcompat-v7:29.1.1'// https://mvnrepository.com/artifact/androidx.appcompat/appcompat
+    implementation group: 'androidx.appcompat', name: 'appcompat', version: '1.1.0'
+
+
+    testImplementation "org.jetbrains.kotlin:kotlin-test"
+    testImplementation 'junit:junit:4.12'
+
+    androidTestImplementation 'junit:junit:4.12'
+    androidTestImplementation 'com.android.support.test:runner:1.0.2'
+    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+
+
+    def anko_version = "0.10.8"
+    implementation "org.jetbrains.anko:anko-commons:$anko_version"
+}
\ No newline at end of file
diff --git a/mirai-demos/mirai-demo-android/proguard-rules.pro b/mirai-demos/mirai-demo-android/proguard-rules.pro
new file mode 100644
index 000000000..cf504086a
--- /dev/null
+++ b/mirai-demos/mirai-demo-android/proguard-rules.pro
@@ -0,0 +1,22 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
+
diff --git a/mirai-demos/mirai-demo-android/src/main/AndroidManifest.xml b/mirai-demos/mirai-demo-android/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..59f36d365
--- /dev/null
+++ b/mirai-demos/mirai-demo-android/src/main/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="net.mamoe.mirai.demo">
+
+    <uses-permission android:name="android.permission.INTERNET"/>
+
+    <application
+            android:name="net.mamoe.mirai.demo.MyApplication"
+            android:allowBackup="true"
+            android:supportsRtl="true"
+            android:theme="@style/AppTheme">
+
+        <activity
+                android:name="net.mamoe.mirai.demo.MainActivity"
+                android:theme="@style/AppTheme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
+    </application>
+</manifest>
diff --git a/mirai-demos/mirai-demo-android/src/main/kotlin/net/mamoe/mirai/demo/ui.kt b/mirai-demos/mirai-demo-android/src/main/kotlin/net/mamoe/mirai/demo/ui.kt
new file mode 100644
index 000000000..8c0352cd2
--- /dev/null
+++ b/mirai-demos/mirai-demo-android/src/main/kotlin/net/mamoe/mirai/demo/ui.kt
@@ -0,0 +1,52 @@
+@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE")
+
+package net.mamoe.mirai.demo
+
+import android.annotation.SuppressLint
+import android.app.Application
+import android.os.Bundle
+import android.widget.LinearLayout
+import androidx.appcompat.app.AppCompatActivity
+import net.mamoe.mirai.Bot
+import net.mamoe.mirai.event.subscribeFriendMessages
+import net.mamoe.mirai.login
+import net.mamoe.mirai.network.protocol.tim.packet.login.requireSuccess
+import net.mamoe.mirai.utils.DefaultLogger
+import net.mamoe.mirai.utils.PlatformLogger
+import net.mamoe.mirai.utils.SimpleLogger
+import java.io.ByteArrayOutputStream
+import java.io.PrintStream
+import kotlin.properties.Delegates
+
+@Suppress("unused")
+private val Throwable.stacktraceString: String
+    get() = ByteArrayOutputStream().also { printStackTrace(PrintStream(it)) }.toString()
+
+class MyApplication : Application()
+
+class MainActivity : AppCompatActivity() {
+    private var rootLayout: LinearLayout by Delegates.notNull()
+
+    @SuppressLint("SetTextI18n")
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_main)
+        rootLayout = findViewById(R.id.main_view)
+
+
+    }
+
+    private suspend fun initializeBot(qq: UInt, password: String) {
+        DefaultLogger = {
+            PlatformLogger(it) + SimpleLogger { message, e ->
+                // TODO: 2019/11/6
+            }
+        }
+
+        val bot = Bot(qq, password).apply { login().requireSuccess() }
+
+        bot.subscribeFriendMessages {
+            "Hello" reply "Hello Mirai!"
+        }
+    }
+}
\ No newline at end of file
diff --git a/mirai-demos/mirai-demo-android/src/main/res/layout/activity_main.xml b/mirai-demos/mirai-demo-android/src/main/res/layout/activity_main.xml
new file mode 100644
index 000000000..520f84b9e
--- /dev/null
+++ b/mirai-demos/mirai-demo-android/src/main/res/layout/activity_main.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/main_view"
+        android:scrollbars="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical"/>
\ No newline at end of file
diff --git a/mirai-demos/mirai-demo-android/src/main/res/values/colors.xml b/mirai-demos/mirai-demo-android/src/main/res/values/colors.xml
new file mode 100644
index 000000000..3ab3e9cbc
--- /dev/null
+++ b/mirai-demos/mirai-demo-android/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#3F51B5</color>
+    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorAccent">#FF4081</color>
+</resources>
diff --git a/mirai-demos/mirai-demo-android/src/main/res/values/styles.xml b/mirai-demos/mirai-demo-android/src/main/res/values/styles.xml
new file mode 100644
index 000000000..5885930df
--- /dev/null
+++ b/mirai-demos/mirai-demo-android/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
+</resources>
diff --git a/mirai-demos/mirai-demo-android/src/test/kotlin/GreetingTest.kt b/mirai-demos/mirai-demo-android/src/test/kotlin/GreetingTest.kt
new file mode 100644
index 000000000..12cb76f87
--- /dev/null
+++ b/mirai-demos/mirai-demo-android/src/test/kotlin/GreetingTest.kt
@@ -0,0 +1,19 @@
+package org.konan.multiplatform
+
+import org.greeting.Greeting
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class GreetingTest {
+
+    @Test
+    fun `should print hello android from android mpp`() {
+        assertEquals(Greeting().greeting(), "Hello, Android")
+    }
+}
+
+// Note that common tests for calculator (i.e. `CalculatorTest`) can be run from `greeting`
+// with `test` Gradle task.
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index f5b8434e8..86e945acf 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -7,8 +7,10 @@ include(':mirai-api')
 include(':mirai-demos:mirai-demo-1')
 include(':mirai-demos:mirai-demo-gentleman')
 include(':mirai-demos')
-include(':mirai-debug')
+include(':mirai-demos:mirai-demo-android')
+//include(':mirai-debug')
 project(':mirai-demos:mirai-demo-1').projectDir = file('mirai-demos/mirai-demo-1')
 project(':mirai-demos:mirai-demo-gentleman').projectDir = file('mirai-demos/mirai-demo-gentleman')
+project(':mirai-demos:mirai-demo-android').projectDir = file('mirai-demos/mirai-demo-android')
 
-enableFeaturePreview('GRADLE_METADATA')
+enableFeaturePreview('GRADLE_METADATA')
\ No newline at end of file