タスクの前提条件
携帯電話で本を読むのが大好きで、これらの本から引用をツイートするのが大好きです。 しかし、これらの本には通常140文字を超える引用が含まれているため、状況はやや面倒でした。 この問題は次の2つの方法で解決できます。
- 複数のツイートで引用を送信する
- 写真付きのテキストをツイートします。
それは私にとってそれほど恐ろしくない2番目の道でした。 その結果、一連のアクションで使用されるアプリケーションが作成されます。任意のアプリケーションからテキストを共有します->プログラムにアクセスします->すでに任意のアプリケーションに画像を共有します
結果のプロジェクトから何を学ぶことができるか
- コトリンの長所を見てください
- Gradleの典型的なビルドスクリプトを見てください
- テキストを長方形に収めるためのフォントサイズを計算する機能、他の人のアプリケーションから共有されたテキストを受信する機能、他の人のアプリケーションで写真を共有する機能などを削除します。
コトリンの利点
先月、Xamarinへの栄光* 、. NET携帯電話(C#)で書きました。 その後、Android(Android 4.1+で記述したい場合は制限付きのJava 7が支配する)に戻ることは不快ではありませんが、コントラストは非常に顕著です。 砂糖だけでは十分ではありません。 Kotlinはコードを簡潔に記述できることに大いに満足しており、マシンがルーチンのかなりの部分を実行します。
読み取り専用フィールドを持つPOJOクラスだけを宣言する必要がありますか? 簡単です。
public class Size(val width:Int,val height:Int);
変数の型を独立して宣言しますか? しかし、なぜ、コンパイラがそれらを出力できるのか!
val textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG); var paint = Paint();
さらに、 varは変数であり、 valは最終オブジェクトなので、偶然に別の値に置き換えることはできません。
同じコードを使用すると、次のような演算子を減らすことができます。
fun alertError(text:String){ val builder = AlertDialog.Builder(this); with(builder) { setTitle(R.string.error_title) setMessage(text) setPositiveButton(R.string.ok, { dialogInterface, button -> }) } builder.create().show(); }
または、フォーマット機能または同様の意味のないストリング内に変数を固定する機能:
val cachePath = File(getExternalCacheDir(), "temp"); cachePath.mkdirs(); val fileName = "$cachePath/long_text_image.png";
クリックのコールバックには、かなり短いコードも割り当てられます。
buttonSend.setOnClickListener { val text = editText.getText().toString(); // ..... }
また、おそらく既に上記の例に気付いているように、「新しい」演算子もキャンセルされます。
また、静的メソッドに代わるものとしてクラスなしで関数を宣言できる機能も気に入っていました。静的メソッドは、Kotlinにはないことを理解しています。
package com.newbilius.longtextsharer import [...] public fun getMaxFontSizeOfMultilineText(text: String, maxSize: Size, maxTextSize: Int): Float { fun getHeightOfMultiLineText(text: String, textSize: Int, maxWidth: Int): Int { //[...] } var textSize = maxTextSize; while (getHeightOfMultiLineText(text, textSize, maxSize.width) > maxSize.height) textSize--; return textSize.toFloat(); }
また、Kotlin + Androidでは、Kotlinにはすばらしい機能があります-Kotlin Android Extensionsです。 findViewById()を悪夢のように忘れて、耳で次のような気分にさせることができます 。
import kotlinx.android.synthetic.activity._xml__activity.* // ID-, XML' override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_send) editText.setText(getIntent().getStringExtra(Intent.EXTRA_TEXT)); //[...] }
RoboGuiceアノテーションよりも桁違いに便利です。
おそらく、私にとって奇妙に思えた唯一のことは、CallBackを早期に終了するための形式でした。
buttonSend.setOnClickListener { val text = editText.getText().toString(); if (text.length()==0) { alertError(R.string.error_empty_text); return@setOnClickListener; // } //[...] }
Gradleを使用する
現在、Gradleを使用してAndroidアプリを構築することが標準と見なされています。 真実は、Gradleの基礎となるGroovyの開発が年の初めに停止したこと(?)を少し悩ますことです。 まあ、楽観的になりましょう。 デバッグおよびリリースビルドの最小アプリケーションビルドスクリプトは次のようになります。
Gradleスクリプト
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' import groovy.swing.SwingBuilder buildscript { ext.kotlin_version = '0.12.1218' repositories { jcenter() mavenCentral() } dependencies { classpath "com.android.tools.build:gradle:1.1.1" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version" } } repositories { jcenter() mavenCentral() } gradle.taskGraph.whenReady { taskGraph -> if(taskGraph.hasTask(':longtextsharer:assembleRelease')) { def pass = ''; pass = System.console().readPassword("\nPlease enter key passphrase: ") pass = new String(pass) if(pass.size() <= 0) { throw new InvalidUserDataException("You must enter a password to proceed.") } android.signingConfigs.release.storePassword = pass android.signingConfigs.release.keyPassword = pass } } android { compileSdkVersion 22 buildToolsVersion "22.0.1" signingConfigs { release { storeFile file("sign/SET_YOU_KEY.jks") storePassword "" keyAlias "SET_YOU_KEY" keyPassword "" } } defaultConfig { applicationId "com.newbilius.longtextsharer" minSdkVersion 16 targetSdkVersion 22 versionCode 1 versionName "1.0" } buildTypes { debug { debuggable true } release { debuggable false minifyEnabled true signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets { main.java.srcDirs += 'src/main/kotlin' } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:22.2.1' compile 'com.android.support:design:22.2.1' compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" }
ちなみに、リリースバージョンをビルドするためにproguardを使用することを強くお勧めします。これがないと、Kotlinアプリケーションの重量は類似のJavaアプリケーションの5倍になります。 proguardによる処理後、サイズの差は100キロバイト程度でした。 アセンブリのプロガードルールでは、ルールを1つだけ追加する必要がありました。
-dontwarn org.w3c.dom.events.*
ただし、コンソールからではなく、たとえばIntelliJ IDEAから同じスクリプトをビルドすると、問題が発生します。この場合、証明書のパスワードを入力するためのコンソールがありません。 この問題の解決策があるようです -しかし、私には合わなかったので、使用しようとするとエラーが発生しました:
Error:(29, 0) Gradle: Failed to create component for 'dialog' reason: java.awt.HeadlessException > java.awt.HeadlessException (no error message)
おそらくあなたはより幸運であり、あなたは私が間違いを見つけるのを助けるでしょうか? ライブラリ、Java、およびIDE自体のバージョンは最新です。
現地の決定と結論
テキストを四角形に収めたり、アプリケーションを共有したりするためのフォントサイズを計算するための関数の機能はリストしません。すべては、GitHubで説明されているアプリケーションのソースコードにあります。
GitHubのアプリケーションにリンクします。
一般的に、私にとっては、Kotlinのコードはより簡潔でシンプルなので、私の小さなプロジェクトでは引き続き使用します(ソースを共有します)。 このアプリケーションでKotlinまたはGradleのクールな(および適切な)機能を使用していないように思われる場合は、プルリクエストとコメントを待っています!
*栄光は非常に限られており、落とし穴のキロトンをリストする記事が進行中です