少し前に、 TomaszがAndroidでKotlin開発を導入 。あなたに思い出させるために:Kotlinはによって開発された新しいプログラミング言語です ジェットブレインズ 、最も人気のあるJava IDEの1つを開発している会社、 IntelliJ IDEA 。 Javaと同様に、Kotlinは汎用言語です。 Java仮想マシン(JVM)バイトコードに準拠しているため、Javaと並べて使用でき、パフォーマンスのオーバーヘッドは発生しません。
この記事では、Androidの開発を後押しするための便利な機能のトップ10について説明します。
注意 :この記事の執筆時点では、実際のバージョンはAndroid Studio2.1.1でした。およびKotlin1.0.2。
KotlinはJetBrainsによって開発されているため、AndroidStudioとIntelliJの両方で十分にサポートされています。
最初のステップは Kotlinプラグインをインストールします 。これが正常に行われると、JavaをKotlinに変換するための新しいアクションが利用できるようになります。 2つの新しいオプションは次のとおりです。
新しいAndroidプロジェクトを作成する方法については、 公式ステップバイステップガイド 。新しく作成されたプロジェクトまたは既存のプロジェクトにKotlinサポートを追加するには、 アクションダイアログを見つける Command + Shift + A
を使用するMacまたはCtrl + Shift + A
Windows / Linuxで、Configure Kotlin in Project
を呼び出しますアクション。
新しいKotlinクラスを作成するには、次を選択します。
File
> New
> Kotlin file/class
、またはFile
> New
> Kotlin activity
または、Javaクラスを作成し、上記のアクションを使用してKotlinに変換することもできます。これを使用して、任意のクラス、インターフェイス、列挙型、またはアノテーションを変換できます。これを使用して、JavaをKotlinコードと簡単に比較できます。
多くの入力を節約するもう1つの便利な要素は、Kotlin拡張機能です。それらを使用するには、モジュールに別のプラグインを適用する必要がありますbuild.gradle
ファイル:
apply plugin: 'kotlin-android-extensions'
警告 :Kotlinプラグインアクションを使用してプロジェクトを設定している場合、次のコードがトップレベルに配置されますbuild.gradle
ファイル:
buildscript { ext.kotlin_version = '1.0.2' repositories { jcenter() } dependencies { 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 } }
これにより、拡張機能が機能しなくなります。これを修正するには、Kotlinを使用する各プロジェクトモジュールにそのコードをコピーするだけです。
すべてを正しくセットアップすると、標準のAndroidプロジェクトと同じようにアプリケーションを実行およびテストできるようになりますが、現在はKotlinを使用しています。
それでは、Kotlin言語のいくつかの重要な側面を説明し、Javaの代わりにKotlin言語を使用して時間を節約する方法に関するヒントを提供することから始めましょう。
Androidで最も一般的な定型コードの1つは、findViewById()
を使用することです。アクティビティまたはフラグメントのビューへの参照を取得する関数。
次のような解決策があります バターナイフ ライブラリ、入力を節約しますが、Kotlinは、1回のインポートでレイアウトからビューへのすべての参照をインポートできるようにすることで、これをさらに一歩進めます。
たとえば、次のアクティビティXMLレイアウトについて考えてみます。
混合整数計画法とは
package co.ikust.kotlintest import android.support.v7.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) helloWorldTextView.text = 'Hello World!' } }
そして付随する活動コード:
import kotlinx.android.synthetic.main.activity_main.*
定義されたIDを持つレイアウト内のすべてのビューの参照を取得するには、AndroidKotlin拡張機能を使用します あんこ 。次のインポートステートメントを忘れずに入力してください。
TextView
Kotlinの行末にはオプションであるため、セミコロンを記述する必要はありません。
TextView
レイアウトからhelloWorldTextView.text = 'Hello World!'
としてインポートされますビューのIDと同じ名前のインスタンス。ラベルの設定に使用される構文と混同しないでください。
null
これについては後ほど説明します。
警告 :
onCreateView()
が含まれます。値。onCreateView()
関数呼び出し。 onViewCreated()
にレイアウトをインポートします関数を作成し、[参照の表示]を使用してonCreateView()
でUIを設定します。参照はpublic class User { private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
の前に割り当てられませんメソッドが終了しました。Kotlinで最も時間を節約できるのは、データを保持するために使用されるPOJO(Plain Old Java Object)クラスを作成することです。たとえば、RESTfulAPIのリクエストとレスポンスの本文。 RESTful APIに依存するアプリケーションには、そのようなクラスがたくさんあります。
Kotlinでは、多くのことが行われ、構文は簡潔です。たとえば、Javaの次のクラスについて考えてみます。
class MyClass { }
Kotlinを使用する場合、パブリックキーワードを再度記述する必要はありません。デフォルトでは、すべてがパブリックスコープです。たとえば、クラスを宣言する場合は、次のように記述します。
class User { var firstName: String? = null var lastName: String? = null }
上記のKotlinのJavaコードに相当します。
var
ええと、それは多くのタイピングを節約しますね? Kotlinコードを見ていきましょう。
Kotlinで変数を定義する場合、2つのオプションがあります。
val
で定義される可変変数キーワード。null
で定義される不変変数キーワード。次に注意すべきことは、構文がJavaとは少し異なることです。最初に変数名を宣言し、次にタイプを宣言します。また、デフォルトでは、プロパティはnull以外のタイプであるため、null
を受け入れることはできません。値。 firstName
を受け入れる変数を定義するには値の場合、タイプの後に疑問符を追加する必要があります。これとnull-safetyについては後でKotlinで説明します。
注意すべきもう1つの重要な点は、Kotlinにはクラスのフィールドを宣言する機能がないことです。プロパティのみを定義できます。したがって、この場合、lastName
およびclass User { var firstName: String? = null var lastName: String? = null val fullName: String? get() firstName + ' ' + lastName }
デフォルトのゲッター/セッターメソッドが割り当てられているプロパティです。前述のように、Kotlinでは、両方ともデフォルトで公開されています。
カスタムアクセサは、次のように記述できます。
val userName = user.firstName user.firstName = 'John'
外部から見ると、構文に関しては、プロパティはJavaのパブリックフィールドのように動作します。
fullName
新しいプロパティval
に注意してください読み取り専用(lateinit
キーワードで定義)であり、カスタムゲッターがあります。単に名前と姓を追加するだけです。
Kotlinのすべてのプロパティは、宣言時に割り当てるか、コンストラクター内にある必要があります。それが都合が悪い場合があります。たとえば、依存性注入によって初期化されるプロパティの場合です。その場合、class MyClass { lateinit var firstName : String; fun inject() { firstName = 'John'; } }
修飾子を使用できます。次に例を示します。
class User constructor(firstName: String, lastName: String) { }
プロパティの詳細については、 公式ドキュメント 。
Kotlinは、コンストラクターに関しても、より簡潔な構文を持っています。
Kotlinクラスには、プライマリコンストラクタと1つ以上のセカンダリコンストラクタがあります。プライマリコンストラクターの定義例:
class Person(firstName: String) { }
プライマリコンストラクタは、クラス定義のクラス名の後に続きます。プライマリコンストラクタにアノテーションや可視性修飾子がない場合は、コンストラクタキーワードを省略できます。
init
プライマリコンストラクタはコードを持つことができないことに注意してください。初期化はclass Person(firstName: String) { init { //perform primary constructor initialization here } }
で行う必要がありますコードブロック:
class User(var firstName: String, var lastName: String) { // ... }
さらに、プライマリコンストラクタを使用して、プロパティを定義および初期化できます。
val
通常のプロパティと同様に、プライマリコンストラクタから定義されたプロパティは不変(var
)または可変(class User(var firstName: String, var lastName) { constructor(name: String, parent: Person) : this(name) { parent.children.add(this) } }
)にすることができます。
クラスには2次コンストラクターも含まれる場合があります。 1つを定義するための構文は次のとおりです。
this
すべてのセカンダリコンストラクタはプライマリコンストラクタに委任する必要があることに注意してください。これは、class User(val firstName: String, val lastName: String) { constructor(firstName: String) : this(firstName, '') { //... } }
を使用するJavaに似ています。キーワード:
new
クラスをインスタンス化するとき、KotlinにはUser
がないことに注意してくださいJavaと同様に、キーワード。前述のval user = User('John', 'Doe)
をインスタンス化するにはクラス、使用:
価格戦略は、価格目標を達成するためのガイドとして機能します。
Any
Kotlinでは、すべてのクラスがObject
から拡張されます。これは、open
に似ています。 Javaで。デフォルトでは、Javaの最終クラスのように、クラスは閉じられます。したがって、クラスを拡張するには、クラスをabstract
として宣言する必要があります。またはopen class User(val firstName, val lastName) class Administrator(val firstName, val lastName) : User(firstName, lastName)
:
super()
fun add(x: Int, y: Int) : Int { return x + y }
の呼び出しと同様に、拡張クラスのデフォルトコンストラクターに委任する必要があることに注意してください。 Javaの新しいクラスのコンストラクターのメソッド。
クラスの詳細については、チェックしてください 公式ドキュメント 。
Java 8で導入されたラムダ式は、そのお気に入りの機能の1つです。ただし、AndroidではJava 7しかサポートされておらず、Java 8はまもなくサポートされなくなるため、状況はそれほど明るくありません。したがって、次のような回避策 レトロラムダ 、ラムダ式をAndroidに導入します。
Kotlinを使用すると、追加のライブラリや回避策は必要ありません。
Kotlinの関数構文を簡単に確認することから始めましょう。
Int
関数の戻り値は省略できます。その場合、関数はAny
を返します。 Kotlinのすべてがオブジェクトであり、fun add(x: Int, y: Int = 1) : Int { return x + y; }
から拡張されており、プリミティブ型がないことを繰り返す価値があります。
関数の引数には、次のようなデフォルト値を設定できます。
add()
その場合、x
関数は、int add(int x) { Return add(x, 1); } int add(int x, int y) { return x + y; }
のみを渡すことで呼び出すことができます。引数。同等のJavaコードは次のようになります。
add(y = 12, x = 5)
関数を呼び出すときのもう1つの優れた点は、名前付き引数を使用できることです。例えば:
view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(), 'Clicked on view', Toast.LENGTH_SHORT).show(); } };
機能の詳細については、 公式ドキュメント 。
KotlinのLambda式は、Javaでは無名関数と見なすことができますが、構文はより簡潔です。例として、JavaとKotlinでクリックリスナーを実装する方法を示しましょう。
Javaの場合:
view.setOnClickListener({ view -> toast('Click') })
Kotlinの場合:
->
うわー!たった1行のコード!ラムダ式が中括弧で囲まれていることがわかります。パラメータが最初に宣言され、本文はtoast()
の後に続きます符号。クリックリスナーでは、ビューパラメータのタイプは推測できるため、指定されていません。本文は単にview.setOnClickListener({ toast('Click') })
への呼び出しですKotlinが提供するトーストを表示する機能。
また、パラメータが使用されていない場合は、除外することができます。
view.setOnClickListener() { toast('Click') }
KotlinはJavaライブラリを最適化しており、引数に対して1つのメソッドを持つインターフェイスを受け取る関数は、(インターフェイスの代わりに)関数引数を使用して呼び出すことができます。
さらに、関数が最後のパラメーターである場合は、括弧の外に移動できます。
view.setOnClickListener { toast('Click') }
最後に、関数に関数であるパラメーターが1つしかない場合は、括弧を省略できます。
String
詳細については、以下を確認してください Kotlin forAndroid開発者向けの本 アントニオ・レイバと 公式ドキュメント 。
Kotlinは、C#と同様に、拡張関数を使用して既存のクラスを新しい機能で拡張する機能を提供します。たとえば、fun String.md5(): ByteArray { val digester = MessageDigest.getInstance('MD5') digester.update(this.toByteArray(Charset.defaultCharset())) return digester.digest() }
のMD5ハッシュを計算する拡張メソッド:
String
関数名の前には拡張クラスの名前(この場合はthis
)が付いており、拡張クラスのインスタンスはpublic static int toNumber(String instance) { return Integer.valueOf(instance); }
を介して利用できることに注意してください。キーワード。
拡張関数は、Javaユーティリティ関数と同等です。 Javaのサンプル関数は次のようになります。
NullPointerException
サンプル関数は、Utilityクラスに配置する必要があります。つまり、拡張関数は元の拡張クラスを変更しませんが、ユーティリティメソッドを作成する便利な方法です。
Javaで最も苦労することの1つは、おそらくNullPointerExceptions
です。ヌルセーフティはKotlin言語に統合された機能であり、通常は心配する必要がないほど暗黙的です。ザ・ 公式ドキュメント NullPointerException
の唯一の考えられる原因はは:
!!
をスローする明示的な呼び出し。lateinit
を使用する演算子(後で説明します)。UninitializedPropertyAccessException
の場合プロパティは、初期化される前にコンストラクターでアクセスされます、an non-null
スローされます。デフォルトでは、Kotlinのすべての変数とプロパティはnull
と見なされます(null
値を保持できません)null許容として明示的に宣言されていない場合。すでに述べたように、val number: Int? = null
を受け入れる変数を定義する値の場合、タイプの後に疑問符を追加する必要があります。例えば:
val number: Int? = null number.toString()
ただし、次のコードはコンパイルされないことに注意してください。
null
これは、コンパイラがnull
を実行するためです。チェックします。コンパイルするには、val number: Int? = null if(number != null) { number.toString(); }
チェックを追加する必要があります:
number
このコードは正常にコンパイルされます。この場合、Kotlinがバックグラウンドで実行するのは、nun-null
です。 Int
になります(Int?
の代わりにnull
)ifブロック内。
?.
チェックは以下を使用して簡略化できます 安全な通話オペレーター (val number: Int? = null number?.toString()
):
null
2行目は、番号が?:
でない場合にのみ実行されます。あなたも有名なを使用することができます エルビス演算子 (val number Int? = null val stringNumber = number?.toString() ?: 'Number is null'
):
?:
null
の左側の式の場合throw
ではなく、評価されて返されます。それ以外の場合は、右の式の結果が返されます。もう1つの優れた点は、return
を使用できることです。またはfun sendMailToUser(user: User) { val email = user?.email ?: throw new IllegalArgumentException('User email is null') //... }
Kotlinの式であるため、エルビス演算子の右側にあります。例えば:
NullPointerException
!!
が必要な場合Javaの場合と同じ方法でスローされ、NullPointerException
を使用してそれを行うことができます。オペレーター。次のコードはval number: Int? = null number!!.toString()
をスローします。
as
val x: String = y as String
を使用してキャストインを実行キーワード:
ClassCastException
null
をスローするため、これは「安全でない」キャストと見なされます。 Javaのように、キャストが不可能な場合。 val x: String = y as? String
を返す「安全な」キャスト演算子があります例外をスローする代わりに値:
null
キャストの詳細については、 型キャストとキャスト 公式ドキュメントのセクション、およびlateinit
の詳細については安全チェック ヌル-安全性 セクション。
lateinit
プロパティNullPointerException
を使用する場合がありますプロパティにより、class InitTest { lateinit var s: String; init { val len = this.s.length } }
と同様の例外が発生する可能性があります。次のクラスについて考えてみます。
TestClass
このコードは警告なしにコンパイルされます。ただし、UninitializedPropertyAccessException
のインスタンスが発生するとすぐにが作成され、s
プロパティwith()
が原因でスローされます初期化される前にアクセスされます。
with()
関数with(helloWorldTextView) { text = 'Hello World!' visibility = View.VISIBLE }
便利で、Kotlin標準ライブラリが付属しています。オブジェクトの多くのプロパティにアクセスする必要がある場合は、入力を節約するために使用できます。例えば:
times(argument)
オブジェクトと拡張関数をパラメータとして受け取ります。コードブロック(中括弧内)は、最初のパラメーターとして指定されたオブジェクトの拡張関数のラムダ式です。
Kotlinを使用すると、事前定義された演算子のセットにカスタム実装を提供できます。演算子を実装するには、指定された名前のメンバー関数または拡張関数を指定する必要があります。
たとえば、乗算演算子を実装するには、operator fun String.times(b: Int): String { val buffer = StringBuffer() for (i in 1..b) { buffer.append(this) } return buffer.toString() }
という名前のメンバー関数または拡張関数を指定する必要があります。
*
上記の例は、バイナリString
の実装を示しています。 newString
の演算子。たとえば、次の式は値「TestTestTestTest」をval newString = 'Test' * 4
に割り当てます。変数:
==
拡張関数を使用できるため、すべてのオブジェクトの演算子のデフォルトの動作を変更できます。これは両刃の剣であり、注意して使用する必要があります。オーバーロードできるすべての演算子の関数名のリストについては、 公式ドキュメント 。
Javaと比較したもう1つの大きな違いは、!=
です。および==
演算子。演算子a?.equals(b) ?: b === null
次のように変換されます。
!=
while演算子!(a?.equals(b) ?:
次のように変換されます。
==
つまり、equals()
を使用するということですJavaのようにIDチェックを行いません(オブジェクトのインスタンスが同じかどうかを比較します)が、null
と同じように動作します===
と一緒にメソッドチェックします。
IDチェックを実行するには、演算子!==
およびclass SomeClass { var p: String by Delegate() }
Kotlinで使用する必要があります。
特定のプロパティは、いくつかの共通の動作を共有します。例えば:
このようなケースの実装を容易にするために、Kotlinは 委任されたプロパティ :
p
これは、プロパティのゲッター関数とセッター関数がDelegate
であることを意味します。別のクラスのインスタンスString
によって処理されます。
class Delegate { operator fun getValue(thisRef: Any?, property: KProperty): String { return '$thisRef, thank you for delegating '${property.name}' to me!' } operator fun setValue(thisRef: Any?, property: KProperty, value: String) { println('$value has been assigned to '${property.name} in $thisRef.'') } }
の代理人の例プロパティ:
var
上記の例では、プロパティが割り当てられたとき、または読み取られたときにメッセージを出力します。
デリゲートは、可変(val
)プロパティと読み取り専用(getValue
)プロパティの両方に対して作成できます。
読み取り専用プロパティの場合、KProperty
メソッドを実装する必要があります。それは2つのパラメータを取ります( 公式ドキュメント ):
setValue
である必要がありますまたはそのスーパータイプ。この関数は、プロパティまたはそのサブタイプと同じ型を返す必要があります。
可変プロパティの場合、デリゲートはgetValue()
という名前の関数を追加で提供する必要があります。次のパラメータを取ります:
getValue()
と同じ。getValue()
と同じ。Kotlinには、最も一般的な状況をカバーする標準のデリゲートがいくつかあります。
Lazyは、ラムダ式をパラメーターとして受け取る標準のデリゲートです。渡されたラムダ式は、最初に実行されますlazy(LazyThreadSafetyMode.NONE) { … }
メソッドが呼び出されます。
デフォルトでは、レイジープロパティの評価は同期されます。マルチスレッドに関心がない場合は、Delegates.observable()
を使用できます。余分なパフォーマンスを得るために。
2018年の美容業界の価値はいくらですか
setValue()
ObserverパターンでObservablesとして動作する必要があるプロパティ用です。初期値と3つの引数(プロパティ、古い値、新しい値)を持つ関数の2つのパラメーターを受け入れます。
指定されたラムダ式は毎回実行されますclass User { var email: String by Delegates.observable('') { prop, old, new -> //handle the change from old to new value } }
メソッドが呼び出されます:
Delegates.observable()
この標準デリゲートは、プロパティに割り当てられた新しい値を保存するかどうかを決定できる特別な種類のObservableです。値を割り当てる前に、いくつかの条件を確認するために使用できます。 true
と同様に、初期値と関数の2つのパラメーターを受け入れます。
違いは、関数がブール値を返すことです。 var positiveNumber = Delegates.vetoable(0) { d, old, new -> new >= 0 }
が返される場合、プロパティに割り当てられた新しい値が保存されるか、破棄されます。
class User(val map: Map) { val name: String by map val age: Int by map }
与えられた例は、プロパティに割り当てられた正の数のみを格納します。
詳細については、 公式ドキュメント 。
一般的な使用例は、プロパティの値をマップ内に格納することです。これは、RESTful APIと連携し、JSONオブジェクトを解析するアプリケーションでよく発生します。この場合、マップインスタンスは、委任されたプロパティの委任として使用できます。からの例 公式ドキュメント :
User
この例では、val user = User(mapOf( 'name' to 'John Doe', 'age' to 25 ))
マップを取得するプライマリコンストラクタがあります。 2つのプロパティは、プロパティ名と同じキーの下にマップされているマップから値を取得します。
MutableMap
新しいユーザーインスタンスのnameプロパティには、「John Doe」の値が割り当てられ、ageプロパティには値25が割り当てられます。
これは、class MutableUser(val map: MutableMap) { var name: String by map var age: Int by map }
と組み合わせたvarプロパティで機能します同じように:
any
Kotlinでのラムダのサポートにより、コレクションを新しいレベルに活用できます。
まず、Kotlinは可変コレクションと不変コレクションを区別します。たとえば、2つのバージョンがあります 反復可能 インターフェース:
同じことが言えます コレクション 、 リスト 、 セットする そして 地図 インターフェイス。
たとえば、これはtrue
操作はval list = listOf(1, 2, 3, 4, 5, 6) assertTrue(list.any { it % 2 == 0 })
を返します少なくとも1つの要素が指定された述語に一致する場合:
.apk
コレクションで実行できる機能操作の広範なリストについては、これを確認してください ブログ投稿 。
Kotlinが提供するものの表面をかじったところです。さらに読み、さらに学ぶことに興味がある人は、以下を確認してください。
要約すると、Kotlinはネイティブを書くときに時間を節約する機能を提供します アンドロイド 直感的で簡潔な構文を使用したアプリケーション。それはまだ若いプログラミング言語ですが、私の意見では、本番アプリの構築に使用できるほど安定しています。
Kotlinを使用する利点:
欠点:
.apk
にライブラリを追加するため、最終的な|_+_|サイズは約300KB大きくなります。