聲明:本文是作者AWeiLoveAndroid原創(chuàng),版權(quán)歸作者AWeiLoveAndroid所有,侵權(quán)必究。如若轉(zhuǎn)發(fā),請(qǐng)注明作者和來(lái)源地址!未經(jīng)授權(quán),嚴(yán)禁私自轉(zhuǎn)載!
我本來(lái)是不想學(xué)習(xí)kotlin的,但是現(xiàn)在的形勢(shì),很多公司都在使用kotlin開(kāi)發(fā),可以說(shuō)學(xué)會(huì)kotlin也是無(wú)奈之舉,既然是潮流,谷歌也在大力推廣,所以還是只能硬著頭皮逼迫自己學(xué)一下,也能更快適應(yīng)公司的需要。正所謂:“識(shí)時(shí)務(wù)者為俊杰”,改變不了公司的發(fā)展,那就改變自己。本文首發(fā)在 慕課網(wǎng),轉(zhuǎn)載請(qǐng)注明原文鏈接和作者信息。
廢話少說(shuō),直接上正題。本文主要講解kotlin和java混合開(kāi)發(fā)的一個(gè)初探。這是一個(gè)入門篇的總結(jié)博客。我這里使用的Kotlin版本是最新的版本,版本號(hào)是 1.3.0
目錄
本文配套源碼請(qǐng)看github:https://github.com/AweiLoveAndroid/Kotlin-learn/
一、Kotlin集成步驟和注意事項(xiàng)(基于Kotlin1.3.0):
1.在工程根目錄的 build.gradle 里面的 buildscript 節(jié)點(diǎn)的 dependencies 子節(jié)點(diǎn) 添加一行依賴:
buildscript {
dependencies {
// 添加這一行依賴
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
2.在工程根目錄 build.gradle 的buildscript節(jié)點(diǎn) 配置kotlin版本號(hào):
buildscript {
ext.kotlin_version = '1.3.0'
...
}
3.在項(xiàng)目module的 build.gradle 的頂部添加以下代碼:
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
4.在項(xiàng)目module的 build.gradle的dependencies 節(jié)點(diǎn)里添加以下代碼:
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}
5.注意事項(xiàng):
1.本地kotlin版本路徑:
Android Studio安裝根路徑/gradle/m2repository/org/jetbrains/kotlin/kotlin-stdlib/
2.不同了版本的依賴庫(kù)
1.2.0以前使用這個(gè)依賴庫(kù)
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
1.2.0+版本使用這個(gè)依賴庫(kù)
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
3.Tools --> kotlin --> Decompiler Kotlin to Java,如果該選項(xiàng)是灰色,請(qǐng)下載插件
Java Bytecode Decompiler
4.這幾個(gè)依賴庫(kù)的區(qū)別:
| 依賴庫(kù)名稱 | 含義 |
|---|---|
| implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" | 1.2.0版本以前使用的配置,兼容java7 |
| implementation "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" | 1.2.0以前使用的配置,兼容java8 |
| implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" | 1.2.0+版本以前使用的配置,兼容java7 |
| implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" | 1.2.0+版本使用的配置,兼容java8 |
5.Kotlin下載到本地的路徑在哪里?
工程目錄的末尾有個(gè)External Libraries,選擇某一個(gè)kotlin的jar包,打開(kāi),
右鍵選擇 Show in Explorer,就可以看到kotlin的jar包和資源下載在本地的路徑了。
如下圖所示:
kotlin的所有jar下載的路徑為:
C:/Users/Administrator/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/
Users是我的電腦名。
如下圖所示:
二、Kotlin和Java文件互相轉(zhuǎn)換
(1)Java轉(zhuǎn)Kotlin
- 1.選中Java文件,點(diǎn)擊菜單欄
Code-->Convert Java File to Kotlin File,即可把java文件轉(zhuǎn)換成kotlin文件。
- 2.點(diǎn)擊右上角提示的
configue,然后會(huì)出現(xiàn)一個(gè)彈窗。
- 3.設(shè)置工程里面哪些需要配置kotlin文件支持。比如我這里選中的是
single module,module名為kotlinlibrary。還可以選擇kotlin的編譯和運(yùn)行版本號(hào),比如我選擇的1.2.30,然后點(diǎn)擊OK即可,如下圖所示。
- 4.然后我們就可以看到項(xiàng)目根路徑的
build.gradle和kotlinlibrary這個(gè)module的build.gradle都做了kotlin的配置。如圖所示:
根路徑的
build.gradle配置:
kotlinlibrary的build.gradle配置:
(2)Kotlin轉(zhuǎn)Java
點(diǎn)擊菜單欄Tools-->Kotlin-->Decompile Kotlin To Java 就可以了,我用的AS3.1.3,不知道為啥我的是灰色的?有人可以告訴我原因嗎?
三、Kotlin項(xiàng)目里面集成Java的module
這一部分源碼請(qǐng)看github:https://github.com/AweiLoveAndroid/Kotlin-learn/tree/master/KotlinAndJavaDemo
(1)創(chuàng)建一個(gè)名為 KotlinAndJavaDemo 的項(xiàng)目創(chuàng)建一個(gè)module,取名為JavaModule,跟普通創(chuàng)建一樣,只是最后一步要選擇使用的語(yǔ)言是Java,如圖所示:
(2)項(xiàng)目代碼和平常使用Java開(kāi)發(fā)一樣。
代碼、資源文件、預(yù)覽圖都和平時(shí)開(kāi)發(fā)是一樣的。
(3)如果我們是一個(gè)Java的lib庫(kù),kotlin也是可以直接調(diào)用的。
我的kotlin的module名為app, 依賴了一個(gè)java的名為javalibrary的lib。我需要在app里面使用javalibrary的ResourcesUtils,然后獲取狀態(tài)欄高度,如果成功,就彈吐司顯示狀態(tài)欄高度。
這個(gè)是
javalibrary的ResourcesUtils:
/**
* 描述:
* 資源工具類
*/
public class ResourcesUtils {
/**
* 獲取狀態(tài)欄高度
* @return 狀態(tài)欄高度
*/
public static int getStatusBarHeight(Context context) {
//獲取status_bar_height資源的ID
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
//根據(jù)資源ID獲取響應(yīng)的尺寸值
return context.getResources().getDimensionPixelSize(resourceId);
} else {
return dip2px(context,24f);
}
}
// dp 轉(zhuǎn)成 px
private static int dip2px(Context context, Float dpValue) {
float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
再來(lái)看看
app的MainActivity里面的使用:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
init(this)
}
fun init(context: Context) {
val statusBarHeight = ResourcesUtils.getStatusBarHeight(context)
Toast.makeText(context, "狀態(tài)欄高度為:$statusBarHeight",Toast.LENGTH_SHORT).show()
}
}
(4)我們?cè)诳纯纯赐暾墓こ探Y(jié)構(gòu)圖
四、Java項(xiàng)目里面集成Kotlin的module
這一部分源碼請(qǐng)看github:https://github.com/AweiLoveAndroid/Kotlin-learn/tree/master/JavaAndKotlinDemo
(1)創(chuàng)建一個(gè)名為 KotlinAndJavaDemo 的項(xiàng)目創(chuàng)建一個(gè)module,取名為KotlinModule,跟普通創(chuàng)建一樣,只是最后一步要選擇使用的語(yǔ)言是Kotlin,如圖所示:
(2)項(xiàng)目代碼和平常使用Kotlin開(kāi)發(fā)一樣。
(3)如果我們是一個(gè)Kotlin的lib庫(kù),Java也是可以直接調(diào)用的。
我的Java的module名為app, 依賴了一個(gè)Kotlin的名為kotlinlibrary的lib。我需要在app里面使用kotlinlibrary的ResourcesUtils,然后獲取狀態(tài)欄高度,如果成功,就彈吐司顯示狀態(tài)欄高度。
這個(gè)是
kotlinlibrary的ResourcesUtils:
package com.lzw.kotlinlibrary
import android.content.Context
/**
* 描述:
* 資源工具類
*/
class ResourcesUtils {
// 伴生對(duì)象 這里面包裹的方法 實(shí)際上類似于java的靜態(tài)方法
companion object {
/**
* 獲取狀態(tài)欄高度
* @return 狀態(tài)欄高度
*/
fun getStatusBarHeight(context: Context): Int {
//獲取status_bar_height資源的ID
val resourceId = context.resources.getIdentifier("status_bar_height", "dimen", "android")
return if (resourceId > 0) {
//根據(jù)資源ID獲取響應(yīng)的尺寸值
context.resources.getDimensionPixelSize(resourceId)
} else {
dip2px(context, 40f)
}
}
/**
* dp 轉(zhuǎn) px(像素)
*/
fun dip2px(context: Context, dpValue: Float?): Int {
val scale = context.resources.displayMetrics.density
return (dpValue!! * scale + 0.5f).toInt()
}
/**
* px(像素) 的單位 轉(zhuǎn) dp
*/
fun px2dip(context: Context, pxValue: Float?): Int {
val scale = context.resources.displayMetrics.density
return (pxValue!! / scale + 0.5f).toInt()
}
}
}
再來(lái)看看
app的MainActivity里面的使用:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init(this);
}
private void init(Context context) {
int statusBarHeight = ResourcesUtils.Companion.getStatusBarHeight(context);
Toast.makeText(context, "狀態(tài)欄高度為:" + statusBarHeight + "像素",Toast.LENGTH_SHORT).show();
}
}
(4)我們?cè)诳纯纯赐暾墓こ探Y(jié)構(gòu)圖
五、同一個(gè)module同時(shí)使用Java和Kotlin
(一)給kotlin文件單獨(dú)配置文件路徑
我們還是拿第一個(gè)前面的工程KotlinAndJavaDemo為例,我在moduleapp里面同時(shí)使用kotlin和java兩種語(yǔ)言做開(kāi)發(fā)。 為了便于區(qū)分,需要在該module的build.gradle文件做配置。
默認(rèn)情況,Kotlin文件存放在src/main/java/文件夾下。若是需要隔開(kāi)java文件和Kotlin文件,我們可以指定一個(gè)專門存放Kotlin文件的文件夾, 首先在src/main目錄下創(chuàng)建文件夾kotlin,然后做以下配置:
android {
// 配置一個(gè)路徑專門存放kotlin文件
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
圖示如下:
(二)代碼里面的使用
(1)如果主工程是kotlin寫(xiě)的,部分是Java寫(xiě)的。
比如Activity是kotlin寫(xiě)的,工具類是java寫(xiě)的,實(shí)例代碼如下:
package com.lzw.kotlinandjavademo
import android.content.Context
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.widget.Toast
// 使用本包名里面的對(duì)應(yīng)文件
import com.lzw.kotlinandjavademo.util.ResourcesUtils
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
init(this)
}
fun init(context: Context) {
val statusBarHeight = ResourcesUtils.getStatusBarHeight(context)
Toast.makeText(context, "狀態(tài)欄高度為:$statusBarHeight 像素", Toast.LENGTH_SHORT).show()
Log.e("tag", "狀態(tài)欄高度為:$statusBarHeight 像素")
}
}
工程目錄結(jié)構(gòu)如圖所示:
(2)如果主工程是Java寫(xiě)的,部分是Kotlin寫(xiě)的。
比如Activity是Java寫(xiě)的,工具類是kotlin寫(xiě)的,實(shí)例代碼如下:
package com.lzw.javaandkotlindemo;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
import com.lzw.javaandkotlindemo.util.ResourcesUtils;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init(this);
}
private void init(Context context) {
int statusBarHeight = ResourcesUtils.Companion.getStatusBarHeight(context);
Toast.makeText(context, "狀態(tài)欄高度為:" + statusBarHeight + "像素",Toast.LENGTH_SHORT).show();
}
}
工程目錄結(jié)構(gòu)如圖所示: