Monday, May 22, 2017

Android Studio 3.0 Canary with Kotlin

Peamon Calculator, java source code converted to Kotlin
Modifications to the following files are needed for Android Studio 3.0 Canary 1

app/build.gradle    Select all
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { compileSdkVersion 23 buildToolsVersion '26.0.0 rc2' // for Android Studio 3.0 Canary 1 defaultConfig { applicationId "com.example.peamoncalculator" minSdkVersion 22 targetSdkVersion 23 versionCode 1 versionName "1.0" archivesBaseName = "PeamonCalculator" + versionName testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23+' compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.android.support:design:23+' // Required for local unit tests testCompile 'junit:junit:4.12' // Required for instrumented tests androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' androidTestCompile 'com.android.support.test:runner:0.5' androidTestCompile 'com.android.support:support-annotations:23+' compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" } repositories { mavenCentral() } // add these tasks in run config to make kotlin test working // for junit task copyTestClasses(type: Copy) { from "build/tmp/kotlin-classes/debugUnitTest" into "build/intermediates/classes/debug" } // for instrumented test task copySdkClasses(type: Copy) { from "build/tmp/kotlin-classes/debug" into "build/intermediates/classes/debug" } afterEvaluate { compileDebugUnitTestSources.dependsOn copyTestClasses compileReleaseUnitTestSources.dependsOn copyTestClasses compileDebugAndroidTestSources.dependsOn copySdkClasses }




gradle-wrapper.properties    Select all
distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-milestone-1-all.zip



Project/build.gradle    Select all
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext.kotlin_version = '1.1.2-4' repositories { maven { url 'https://maven.google.com' } jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.0.0-alpha1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() maven { url 'https://maven.google.com' } mavenCentral() } } task clean(type: Delete) { delete rootProject.buildDir }



app/src/main/java/com/example/peamoncalculator/MainActivity.kt    Select all
// Converted to Kotlin for Android Studio 3.0 Canary 1 package com.example.peamoncalculator import android.app.Activity import android.os.Bundle import android.support.design.widget.FloatingActionButton import android.support.design.widget.Snackbar import android.support.v7.app.AppCompatActivity import android.support.v7.widget.Toolbar import android.view.View import android.view.Menu import android.view.MenuItem import android.view.View.OnClickListener import android.widget.Button import android.widget.EditText import android.widget.TextView class MainActivity : Activity(), OnClickListener { private var Scr: EditText? = null // textbox screen private val debugScr: EditText? = null // debug screen private var NumberBf: Float = 0.toFloat() //save screen before pressing button operation; private var Operation = "" private var LastOperation = "" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Scr = findViewById(R.id.editText) as EditText println("OK Calculator") // set debug screen text val idList = intArrayOf(R.id.button1, R.id.button2, R.id.button3, R.id.button4, R.id.button5, R.id.button6, R.id.button7, R.id.button8, R.id.button9, R.id.button0, R.id.buttonAdd, R.id.buttonSub, R.id.buttonMul, R.id.buttonDiv, R.id.buttonDot, R.id.buttonEq) for (id in idList) { val v = findViewById(id) v.setOnClickListener(this) println("It comes here " + (v as Button).text.toString()) } } // Have to implement with the OnClickListner // onClick is called when a view has been clicked. override fun onClick(v: View) { // Parameter v stands for the view that was clicked. println("Pressed Button " + (v as Button).text.toString()) val eqButton = findViewById(R.id.buttonEq) as Button eqButton.text = "=" when (v.id) { R.id.buttonAdd -> { sMath("+") LastOperation = "+" } R.id.buttonSub -> { sMath("-") LastOperation = "-" } R.id.buttonMul -> { sMath("*") LastOperation = "*" } R.id.buttonDiv -> { sMath("/") LastOperation = "/" } R.id.buttonEq -> { if (LastOperation == "=") { Scr!!.setText("0") NumberBf = 0f Operation = "" LastOperation = "=" //break } LastOperation = "=" eqButton.text = "C" sResult() } else -> { val numb = (v as Button).text.toString() getKeyboard(numb) } } } fun sMath(str: String) { NumberBf = java.lang.Float.parseFloat(Scr!!.text.toString()) // save the screen Operation = str // save operation Scr!!.setText("0") // clear screen } fun getKeyboard(str: String) { var ScrCurrent = Scr!!.text.toString() if (ScrCurrent == "0") ScrCurrent = "" if (ScrCurrent.contains(".") and (str == ".")) return ScrCurrent += str Scr!!.setText(ScrCurrent) } fun sResult() { val NumberAf = java.lang.Float.parseFloat(Scr!!.text.toString()) var result = 0f if (Operation == "+") { result = NumberBf + NumberAf } if (Operation == "-") { result = NumberBf - NumberAf } if (Operation == "*") { result = NumberBf * NumberAf } if (Operation == "/") { result = NumberBf / NumberAf } Scr!!.setText(result.toString()) } override fun onCreateOptionsMenu(menu: Menu): Boolean { // Inflate the menu; this adds items to the action bar if it is present. menuInflater.inflate(R.menu.menu, menu) return true } override fun onOptionsItemSelected(item: MenuItem): Boolean { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. val id = item.itemId if (id == R.id.action_settings) { println("Settings") return true } return super.onOptionsItemSelected(item) } }



app/src/main/res/layout/activity_main.xml    Select all
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" tools:context="com.example.peamoncalculator.MainActivity" > <EditText android:text="0" android:id="@+id/editText" android:layout_width="fill_parent" android:layout_height="fill_parent" android:maxLength="12" android:textSize="50sp" android:layout_weight="0.6" android:gravity="right" android:hint="0"> </EditText> <TableLayout android:id="@+id/tableLayout1" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="0.2"> <TableRow android:id="@+id/tableRow1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25"> <Button android:text="1" android:id="@+id/button1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> <Button android:text="2" android:id="@+id/button2" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> <Button android:text="3" android:id="@+id/button3" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> <Button android:text="4" android:id="@+id/button4" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> </TableRow> <TableRow android:id="@+id/tableRow2" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25"> <Button android:text="5" android:id="@+id/button5" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> <Button android:text="6" android:id="@+id/button6" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> <Button android:text="7" android:id="@+id/button7" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> <Button android:text="8" android:id="@+id/button8" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> </TableRow> <TableRow android:id="@+id/tableRow3" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25"> <Button android:text="9" android:id="@+id/button9" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> <Button android:text="0" android:id="@+id/button0" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> <Button android:text="." android:id="@+id/buttonDot" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> <Button android:text="=" android:id="@+id/buttonEq" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> </TableRow> <TableRow android:id="@+id/tableRow4" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25"> <Button android:text="+" android:background="#8FCC8F" android:id="@+id/buttonAdd" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> <Button android:text="-" android:background="#8FBC8F" android:id="@+id/buttonSub" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> <Button android:text="*" android:background="#8FCC8F" android:id="@+id/buttonMul" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> <Button android:text="/" android:background="#8FBC8F" android:id="@+id/buttonDiv" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.25" android:textSize="30sp"></Button> </TableRow> </TableLayout> </LinearLayout>





C++ Example

The original HelloDroid project file for Android 1.3 is from https://mega.nz/#!iwoHjDiC!dJ45TLYAmCoUYnSOE9H1faYYOSyt5FxfBnmlXeqIRgU

Modifications to the following files are needed for Android Studio 3.0 Canary 1

app/build.gradle    Select all
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion '25.0.2' // minimum 25.0.x for Android Studio 3.0 Canary 1 defaultConfig { applicationId 'com.beginndkgamecode.hellodroid' minSdkVersion 9 targetSdkVersion 23 versionCode 1 versionName "1.0" archivesBaseName = 'HELLODRIOD_' + versionName ndk { abiFilters 'armeabi-v7a', 'x86', 'x86_64' } externalNativeBuild { ndkBuild { arguments "NDK_APPLICATION_MK=src/main/jni/Application.mk", "-j6" } } } buildTypes { debug { minifyEnabled false zipAlignEnabled true debuggable true useProguard false } release { minifyEnabled false zipAlignEnabled true useProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } externalNativeBuild { ndkBuild { path "src/main/jni/Android.mk" } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23+' compile 'com.android.support.constraint:constraint-layout:1.0.0+' }

app/src/main/jni/Application.mk    Select all
APP_PLATFORM := android-9 APP_ABI := armeabi-v7a x86 x86_64

Project:HelloDroid/build.gradle    Select all
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { //classpath 'com.android.tools.build:gradle-experimental:0.7.0-beta1' //classpath 'com.android.tools.build:gradle:2.2.0-alpha3' //updated classpath for Android Studio 3.0 classpath 'com.android.tools.build:gradle:3.0.0-alpha1' } } allprojects { repositories { jcenter() } }



gradle-wrapper.properties    Select all
distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists #updated to gradle-4.0-milestone-1-all.zip for Android Studio 3.0 distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-milestone-1-all.zip



app/src/main/jni/Android.mk    Select all
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hellodroid LOCAL_SRC_FILES := main.cpp LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2 LOCAL_STATIC_LIBRARIES := android_native_app_glue include $(BUILD_SHARED_LIBRARY) $(call import-module,android/native_app_glue)



ATTENTION: Quit Docker (if running) before launching Android Emulator in HAXM.






Install kotlin compiler in macOS


shell script     Select all
# install kotlin in macOS, also applicable to Ubuntu Linux # for Ubuntu, sdk install java curl -s https://get.sdkman.io | bash # open another Terminal sdk install kotlin # create hello.kt cat > hello.kt <<"EOF" fun main(args: Array<String>) { println("Hello, World!") val list = listOf(1, 3, 5, 7) for (k in list) { println("k is $k") } list.forEach(fun(x) { println("x is $x") }) args.forEachIndexed(fun(x, y) { println("arg[$x] is $y") }) } EOF # compile and test hello.kt kotlinc hello.kt -include-runtime -d hello.jar java -jar hello.jar a b c d



No comments: