1. ホーム
  2. アンドロイド

[解決済み】AndroidプロジェクトでThreeTenABPを使用する方法

2022-04-21 08:37:50

質問

私は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)

解決方法は?

ご注意ください。この回答は、技術的には正しいのですが、現在では古くなっています。

Android Gradle Plugin 4.0.0+ で Java 8+ API desugaring をサポートしました。

(また 以下、バジル・ブルック氏の回答 )

に関する開発 ThreeTenABPライブラリ が一段落しました。今後、Android Gradle プラグイン 4.0, java.time.*, およびそのコアライブラリのデスガリング機能への切り替えをご検討ください。

これらの言語APIをAndroidプラットフォームのどのバージョンでもサポートできるようにするには、以下のように 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.time , スリーテンバックポート あるいは ジョダイム

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

最も明白な解決策は、ビルトインの java.time これは、Javaで時刻と日付を扱う新しい標準的な方法だからです。の実装です。 JSR 310 に基づく時間処理の新しい標準的な提案でした。 Joda-Time(ジョダタイム ライブラリです。

しかし java.time に導入されました。 ジャバ8 . までのAndroid マシュマロ はJava 7で動作します("Android N"はJava 8の言語機能を導入する最初のバージョンです)。したがって アンドロイドN ヌガー 以上では、Java 8の言語機能に頼ることはできません(実はこれが100%正しいとは言い切れませんが、私はこのように理解しています)。そのため java.time はアウトです。

次のオプションは ジョダタイム 以来 JSR 310 はJoda-Timeをベースにしていました。しかし ThreeTenABP readme が示すように、様々な理由から、Joda-Timeは最適な選択肢ではありません。

次は スリーテン・バックポート これは、Java 8 の大部分 (すべてではない) をバックポートしたものである。 java.time の機能をJava 7に移植しました。これはほとんどのユースケースで問題ありませんが ThreeTenABP readme Androidでは性能的に問題があります。

ということで、最後の、一見正しいように見える選択肢は スリーテンABP .

第二の発見。ビルドツールと依存関係管理

プログラムのコンパイル、特に外部ライブラリを大量に使用するものは複雑なので、Javaではほとんど必ずといっていいほど ビルドツール。 を使用して、そのプロセスを管理します。 作る , Apache Ant , アパッチ・メイブン および グラドル はすべて、Java プログラムで使用されるビルドツールです ( この記事 をご覧ください。) さらに下に記載したように、AndroidプロジェクトではGradleがビルドツールとして選ばれています。

これらのビルドツールには依存関係管理も含まれています。Apache Mavenは、集中型パッケージリポジトリを初めて搭載したようです。Maven は Maven中央リポジトリ と同等の機能を実現します。 composer をPackagistで、Rubyの gem のようなものです。言い換えれば、Maven Central RepositoryはMaven(とGradle)にとって、Packagistがcomposerにとってそうであるように、バージョン管理されたパッケージの決定的で安全なソースなのです。

第三の発見。GradleはAndroidプロジェクトの依存関係を処理する

Gradleのドキュメントを読むことが私のTo-Doリストの上位にあります。 こちら 無料のeBookも含めて。もし私がAndroidを学び始めた数週間前にこれらを読んでいたら、GradleがAndroidプロジェクトの依存関係を管理するためにMaven Central Repositoryを使用できることを確実に知っていたことでしょう。さらに、下記で詳しく説明されているように これ StackOverflow の回答では、Android Studio 0.8.9 の時点で、Gradle は Bintray の JCenter を通して暗黙的に Maven Central Repository を使用するようになっており、レポをセットアップするために余計な設定をする必要がない -- 依存関係をリストするだけだ。

第四の発見。プロジェクトの依存関係は[project dir]/app/build.gradle にリストアップされます。

JavaでGradleを使ったことがある人にとっては当たり前のことですが、私はこれを理解するのに時間がかかりました。もし、人々が "ああ、ちょうど追加してください compile 'this-or-that.jar' ということを知ることです。 compile は、そのbuild.gradleファイルの中で、コンパイル時の依存性を示すディレクティブです。 ここでは 依存関係管理に関するGradleの公式ページです。

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

またもや、時間をかけすぎてしまった問題です。Maven CentralでThreeTenを探すと、以下のパッケージしか表示されません。 threetenbp ではなく threetenabp . もし、あなたが ThreeTenABPのgithubリポジトリ を見ると、インファマス compile 'this-or-that' の行は、ReadmeのDownloadセクションの下にあります。

この github リポを最初に見たとき、このコンパイル行の意味がわからず、ターミナルで実行しようとしました(明らかに予想通りの失敗でした)。イライラして、残りの部分を理解した後、ずっとこの行に戻らなかったのですが、最終的に、この行は、Maven Repo の com.jakewharton.threetenabp のレポに対して org.threeten のレポです。だからThreeTenABPパッケージはMavenレポにないと思ったんです。

まとめ:動作させる

これで、すべてがかなり簡単になったように見えます。Android プロジェクトで最新の時刻処理機能を利用するには、プロジェクト内の [project folder]/app/build.gradle ファイルには implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1' の行は、その 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);
        //...
    }
}