AndroidプロジェクトでThreeTenABPを使用する方法


192

私はJavaとAndroidが初めてで、これを理解しようと何時間も検索したので、この質問をしました。答えは関連する答えの組み合わせから来たので、私は苦労している可能性のある他の人のために私が学んだことを文書化すると思いました。答えを見てください。

Android Studio 2.1.2を使用していますが、Javaセットアップは次のとおりです。

>java -version
> openjdk version "1.8.0_91"
> OpenJDK Runtime Environment (build 1.8.0_91-8u91-b14-3ubuntu1~15.10.1-b14)
> OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)

回答:


192

注意:Java 8以降のAPI設計解除サポート(Android Gradle Plugin 4.0.0以降)

このライブラリ(ThreeTenABP)の開発は終了しています。今後数か月以内に、Android Gradleプラグイン4.0、java.time。*、およびそのコアライブラリの脱糖機能への切り替えを検討してください。

Androidプラットフォームの任意のバージョンでこれらの言語APIのサポートを有効にするには、Androidプラグインを4.0.0(またはそれ以上)に更新し、モジュールのbuild.gradleファイルに以下を含めます。

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  }

  compileOptions {
    // Flag to enable support for the new language APIs
    coreLibraryDesugaringEnabled true
    // Sets Java compatibility to Java 8
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

dependencies {
  coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.5'
}

まずディスカバリー:なぜ持って使用ThreeTenABP代わりのjava.timeThreeTen・バックポート、あるいはジョダタイム

これは、新しい標準を定義する非常に長いプロセスの非常に短いバージョンです。これらのパッケージはすべてほぼ同じものです。Javaに最新の優れた処理機能を提供するライブラリです。違いは微妙ですが重要です。

最も明白な解決策は、組み込みjava.timeパッケージを使用することです。これは、Javaで日時を処理するための新しい標準的な方法だからです。これは、Joda-Timeライブラリに基づく時間処理の新しい標準提案であるJSR 310の実装です。

ただし、Java 8でjava.time導入されました。マシュマロまでのAndroid はJava 7で動作します(「Android N」はJava 8言語機能を導入した最初のバージョンです)。したがって、Android N Nougat以上のみを対象としない限り、Java 8言語機能に依存することはできません(これが100%trueであるかどうかは実際にはわかりませんが、これが私の理解です)。そうjava.timeです。

JSR 310はJoda-Timeに基づいていたため、次のオプションはJoda-Timeかもしれません。ただし、ThreeTenABPのReadmeに示されているように、さまざまな理由から、Joda -Timeは最適なオプションではありません。

次はThreeTen-Backportjava.timeです。これは、Java 8 機能の多く(すべてではない)をJava 7にバックポートします。これは、ほとんどのユースケースで問題ありませんが、ThreeTenABP readmeに示されています。問題いるように、Androidでパフォーマンスの問題があります。

したがって、最後の、一見正しいオプションはThreeTenABPです。

2番目の発見:ビルドツールと依存関係管理

プログラムのコンパイル(特に、外部ライブラリの束を使用するプログラム)は複雑であるため、Javaはほぼ常に「ビルドツール」を使用してプロセスを管理します。MakeApache AntApache Maven、およびGradleはすべて、Javaプログラムで使用されるビルドツールです(比較については、この投稿を参照してください)。後で説明するように、GradleはAndroidプロジェクト用に選択されたビルドツールです。

これらのビルドツールには、依存関係管理が含まれます。Apache Mavenは、集中化されたパッケージリポジトリを最初に組み込んだようです。MavenはMaven Central Repositoryを導入しました。これによりcomposer、Packagist を使用したphp およびrubygems.orgを使用したRubyと同等の機能が可能になりますgem。言い換えると、Mavenセントラルリポジトリは、Maven(およびGradle)にとって、Packagistが作曲するものであり、バージョン管理されたパッケージの確実で安全なソースです。

3番目の発見:GradleがAndroidプロジェクトの依存関係を処理する

私のやるべきことの上位は、無料の電子ブックを含むGradleのドキュメントをここで読むことです。Androidの学習を始めた数週間前に読んだとしたら、GradleがMaven Central Repositoryを使用してAndroidプロジェクトの依存関係を管理できることは確かに知っていただろう。さらに、この StackOverflowの回答で詳しく説明されているように、Android Studio 0.8.9以降では、GradleはBintrayのJCenterを介して暗黙的にMaven Central Repositoryを使用します。つまり、リポジトリを設定するために追加の構成を行う必要はありません。依存関係。

4番目の発見:プロジェクトの依存関係が[project dir] /app/build.gradleにリストされている

繰り返しますが、JavaでGradleを使用した経験のある人には明らかですが、これを理解するにはしばらく時間がかかりました。「ああ、ただ追加するcompile 'this-or-that.jar'」または同様のことを言っている人を見かけたら、それcompileがコンパイル時の依存関係を示すbuild.gradleファイルのディレクティブであることを確認してください。ここだ公式Gradleのページには、依存関係の管理に。

第5の発見:ThreeTenABPはThreeTenではなくJake Whartonによって管理されています

さらに別の問題で、考え出すのに時間がかかりすぎました。Maven CentralでThreeTenを検索するとthreetenbp、のパッケージのみが表示され、は表示されませんthreetenabpThreeTenABPgithubリポジトリにアクセスするcompile 'this-or-that'と、Readmeのダウンロードセクションの下にその悪名高い行が表示されます。

私が最初にこのgithubリポジトリにアクセスしたとき、そのコンパイル行が何を意味するのかわからなかったので、ターミナルで実行しようとしました(明らかで予測可能なエラーが発生しました)。イライラして、私は残りの部分を理解してからしばらくして戻ってきませんでしたが、最終的には、com.jakewharton.threetenabpレポではなくレポを指すMavenレポ行であることに気付きましたorg.threeten。そのため、ThreeTenABPパッケージはMavenリポジトリーに含まれていないと思いました。

要約:機能させる

今ではすべてがかなり簡単に思えます。[project folder]/app/build.gradleファイルに次のimplementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'行があることを確認することで、Androidプロジェクトで最新の処理機能を利用できます。dependenciesセクションに次の。

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "me.ahuman.myapp"
        minSdkVersion 11
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}


dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    testImplementation 'junit:junit:4.12'
    implementation 'com.android.support:appcompat-v7:23.4.0'
    implementation 'com.android.support:design:23.4.0'
    implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'
}

これをApplicationクラスにも追加します。

public class App extends Application {    
    @Override
    public void onCreate() {
        super.onCreate();
        AndroidThreeTen.init(this);
        //...
    }
}

1
素晴らしい投稿をありがとう。ただし、JodaTimeAndroidも検討れているのでしょうか。
ボブ

@ボブ、私はJodaTimeAndroidで実験していませんが、それを必要とするものに今は取り組んでいないからです。私が覚えていることから、java.time実装は問題なく(基本的にはJodaTimeの移植でした)、今後1〜2年でユーザーの90%がNougat +を使用し、開発の実行可能なソリューションになると確信しています。
kael 2017

2
@Bob、JodaTimeは、JSR-310は、おそらく少なく設計上の欠陥を(参照有する以外は、基本的にJSR-310(でも基本的に同じ人によって行われた)と同じで、この記事を、例えば、)。[...下記に続く]
M.プロホロフ2017年

2
コメントを明確にするために… java.timeフレームワーク(JSR 310)は、Joda -Timeプロジェクトの後継者です。どちらのプロジェクトも同じ人物であるスティーブンコールボーンが主導しています。Joda-Timeプロジェクトがメンテナンスモードになり、チームはjava.timeへの移行をアドバイスします。
バジルブルク2018年

6
必ずお電話くださいAndroidThreeTen.init(this)、例えば、APIを使用する前にonCreate().See Android上でThreeTen・バックポート・エラー- ZoneRulesException:いいえタイムゾーンデータファイルが登録
Ole VV

5

kaelが承認した回答は正しいです。さらに、2つのことを述べ、java.time機能の取得に関する図を提供します。

Android 26 以降に組み込まれたjava.time

Android 26以降をターゲットにしている場合は、AndroidにバンドルされているJSR 310java.timeクラス)の実装が見つかります。ThreeTenABPを追加する必要はありません。

ほぼ同じAPI

ただ、明確にするために、ThreeTenABP Android用は適応のあるThreeTen-バックポートのほとんどもたらしライブラリjava.timeのに機能をJavaの6およびJavaの7。このバックポートは、java.timeとほぼ同じAPIを共有しています。

26未満のAndroidをターゲットにしているため、ThreeTenABPを使用するとします。その後、Androidにバンドルされているjava.timeクラスを使用するために、最終的にこれらの以前のバージョンのAndroidのサポートを終了する可能性があります。その場合、import(a)ステートメントの切り替え、および(b)org.threeten.bp.DateTimeUtils古いレガシー日時クラスに追加された新しい変換メソッドを使用するために行った呼び出しを変更すること以外に、コードベースにいくつかの変更を加える必要があります(DateGregorianCalendar) 。

移行プロセスThreeTenABPjava.timeは滑らかとほぼ無痛されるべきです。

どのフレームワークをいつ使用するか

以下のグラフは、3つのフレームワークを示し、どのシナリオでどのフレームワークをいつ使用するかを示しています。

更新: Android Gradle Plugin 4.0.0+は、4つ目の新しいオプションであるAPIのデガガリングにより、以前のAndroidに元々組み込まれていないjava.time機能のサブセットを利用できるようにします。kaelによる主な回答の上部を参照してください。

JavaまたはAndroidのどのバージョンで使用するjava.timeライブラリの表


java.timeについて

java.timeのフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは面倒古い取って代わるレガシーのような日付時刻クラスをjava.util.DateCalendar、& SimpleDateFormat

詳細については、Oracleチュートリアルを参照してください。スタックオーバーフローで多くの例と説明を検索してください。仕様はJSR 310です。

ジョダタイムプロジェクトは、今でメンテナンスモードへの移行をアドバイスjava.timeのクラス。

java.timeオブジェクトをデータベースと直接交換することができます。JDBC 4.2以降に準拠したJDBCドライバーを使用します。文字列もクラスも必要ありません。Hibernate 5とJPA 2.2はjava.timeをサポートしていますjava.sql.*

java.timeクラスはどこで入手できますか?


4

Android StudioのビルドGradleファイルに以下を追加します。

implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'

Applicationクラスを作成し、次のように初期化します。

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        AndroidThreeTen.init(this)
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.