Android Studio でプロジェクトを作成後にリネームする

ささいなことではあるのですが
Android Studio でプロジェクト作成後に，
ちょっと気に入らないとか typo を後で発見したという理由で，
プロジェクト全体の名前をリネームしたいときがあるかもしれません．

実際，適当なプロジェクトをつくって
名前を変えたいなと後で思ったのですが，
実際のところ意外と面倒であるということが分かったので，
あまりオススメされないとは思うものの
どんなものかメモとして書き残そうと思います．


## まず，そのままリファクタしてみよう

`myproject1` というプロジェクトを `mysuperproject1` にリネームすることを考えます．

プロジェクトとしてルートモジュールを `Refactor` > `Rename...` からリネームできそうなので試みるのですが，
実はこれはできないということがわかります:

![myproject1_–_MainActivity_kt__myproject1_app_-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/0e03637f-68c6-5c4f-afc0-76a9e193e6f4.png)

![Screen Shot 2022-02-14 at 20.33.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/ae4338ed-5b53-1f0a-5e7a-a477fc91ab98.png)

![Screen Shot 2022-02-14 at 20.33.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/99e17fbc-4798-ada4-cbbb-c3bc138acbe2.png)

`Can't rename root module` となり，
この方法でルートモジュールはリネームしてくれないのです．
(遊び半分で実行してほしくないのかもしれません)


## プロジェクト名をリネーム

絶対リネームできないのかというと，実はそういうわけでもなくて，
いくつかのステップを踏めばリネームはできなくはないということです．

`settings.gradle` の `rootProject.name` がプロジェクト名になるということで
(https://pleiades.io/help/idea/gradle.html#convert_project_to_gradle)
まずこれを変更します:

![myproject1_–_settings_gradle__myproject1_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/880f2cb6-d992-8e30-4308-7cf1eeceb12d.png)
↓
![mysuperproject1_–_settings_gradle__mysuperproject1_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/02d84a29-3487-93f9-c5f6-f7ed4d3c8abd.png)

その後，Gradle 関連の変更を同期するために `Sync Now` します:

![myproject1_–_settings_gradle__myproject1_-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/dce6af39-71d0-3e5d-ed87-35d7432211f0.png)

そうすると，プロジェクトツリーのルートの表示が変化して，
リネームされたのですよ，という感じになります:

![mysuperproject1_–_settings_gradle__mysuperproject1_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/f66260b5-9248-6c87-1c0a-d2b04dff9702.png)

ただし，表示からなんとなくわかるように，
この状態ではディレクトリ名は一致していません．

プロジェクト名を変更したいほどの人であれば
きっとディレクトリもリネームしたいと思いますから，
プロジェクトをクローズして `mv` なりでリネームし，
再度リネームされたプロジェクトを開きます．

そうすると，表示がいつもどおりになって一致します:

![mysuperproject1_–_settings_gradle__mysuperproject1_-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/e02165c0-8a6e-e558-2fcc-284754f93cf0.png)


## パッケージをリネーム

ここまでで満足した人はここまでで OK です．

お気づきだと思うのですが，
たいていパッケージ名にも含まれているプロジェクト名はそのままで，
きっとパッケージもリネームしたいと思うでしょう．

その場合は，ツリーからパッケージもリネームします:

![mysuperproject1_–_settings_gradle__mysuperproject1_-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/8cb4d71c-da8b-e1f5-03a1-9e9f7eccb165.png)

ところで，このリネームにはこれくらいの影響があるということがわかりますので，
大丈夫そうであることを十分確認して実行します:

![mysuperproject1_–_settings_gradle__mysuperproject1_-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/7f879cfc-f4b2-2787-76fa-8fd7abe2579e.png)

このリファクタを実行すればパッケージはリネームされ，
見えている範囲はおおむね良好になります:

![mysuperproject1_–_MainActivity_kt__mysuperproject1_app__and_20220214.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/9e790c97-f931-52fa-fb1d-4f1e7a0dac8f.png)


## ほかをリネーム

ほかはプロジェクト名を含むリテラルであるとか，
テンプレートから生成されたコードの一部であったりします:

![mysuperproject1_–_MainActivity_kt__mysuperproject1_app__and_20220214.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/8fee0964-10a2-e0b5-7caf-d3e946bc8f91.png)

たとえば生成されたテーマが `MyAppTheme` とかになっているのが例で，
ひょっとすると ここも変更したいと思うかもしれません．

プロジェクト名が `fun` みたいな
よく使われるキーワードだったらヒットしまくって厳しそうですが
`Find in Files...` で検索して
必要な箇所を同様にリファクタでリネームします．

`build.gradle` の `applicationId` は触ってよいのか不安だと思うのですが後述します．

## 慎重になるべきリネーム

よく認知されているように アプリケーション ID まで変えるのは
「[アプリケーション ID を設定する | Android Developers](https://developer.android.com/studio/build/application-id?hl=ja)」にあるように，
アプリ自体が別物として扱われるというのが容易に想像できていると思います．

> アプリケーション ID を変更すると、Google Play ストアは新しいバージョンのアプリをまったく別のアプリとして扱います。
> そのため、アプリを公開したら、**絶対にアプリケーション ID を変更しないでください**。

サンプルして含まれる `Context.packageName` と
ハードコードされた名前を比較するインストゥルメント化テストを実行すると，
当然リネーム後は一致しなくなりますし:
(このためにあったのではないかと思うくらいピッタリなテストですね)

![mysuperproject1_–_ExampleInstrumentedTest_kt__mysuperproject1_app_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/9b4e6001-86b0-ba94-cc5b-138e1880b0d1.png)

![mysuperproject1_–_ExampleInstrumentedTest_kt__mysuperproject1_app_-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/ce15aedd-cae0-c840-fcee-f1d4401106eb.png)

アプリとしても完全に別物になりますね:

![mysuperproject1_–_build_gradle___app_-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359439/1bc9ee94-9349-c186-3068-4220a700560a.png)
(区別できるように `android:label` を変更してあります)

なので，ここまでリネームするケースは，
まだ公開していないプロジェクトに限られると思います．
既存の公開済みアプリでこの影響を承知で
すべてを完璧にリネームしたい開発者はいないのではないかと思えます．

ところで一方，`AndroidManifest.xml` の `package` は変更できて
パッケージと一致していないといけないということです:

> プロジェクトのパッケージ名は、デフォルトでアプリケーション ID と一致していますが、変更することもできます。ただし、パッケージ名を変更する場合は、以下の例に示すように（プロジェクトのディレクトリ構造で定義されている）パッケージ名が `AndroidManifest.xml` ファイル内の `package` 属性と常に一致する必要があることにご注意ください。

> パッケージ名を完全にリファクタリングする場合は、必ず `package` 属性も更新してください。Android Studio のツールを使用してパッケージの名前を変更してリファクタリングすれば、パッケージは自動的に同期が維持されます

このように `build.gradle` の `applicationId` に限らず，
アプリケーション ID のような箇所は影響を調べて慎重になる必要があるでしょう．


## 最後に

僕はビルドシステムを理解しているとはいえないですし，
見様見真似でこれで本当にうまくいっているのかも謎なので，
この手順を行う場合は自己責任でお気をつけください．

名前をつけるのは難しいことだと思うのですが，
プロジェクト開始時に時間をかけてでも
気に入る名前やコードネームをつけておけるに越したことはないですね．