30001


学習中の初心者です。  
Realmで保存するシンプルなデータ（Id, String
contents）を、アプリ起動時に読み込んでグローバル変数として保存しておき、複数のActivityで利用したいと考えています。

グローバル変数の準備として、  
Manifest に `<application android:name=".ThisApp"` を入れ、  
ThisApp に下記のように入れました。

[code]

    public class ThisApp extends Application {
    //グローバルに使用する変数
    public ArrayList<String> GlobalArrayList;
    //初期化メソッド
    public void GlobalArrayList(){
        GlobalArrayList = new GlobalArrayList<String>();
    }
    
[/code]

そしてこのグローバル変数にRealmからデータを入力するのはMainActivityで行おうとして、まずMainActivityの変数定義に
`ThisApp GlobalArrayList;`
を設定し、同じくMainActivityで読み込んだRealmResoltsをセットしようとして、下記のように入れました。

[code]

    //Realmの設定
    Realm mRealm = Realm.getDefaultInstance();
    mRealmResults = mRealm.where(jobCategory.class).findAll();
    mRealm.addChangeListener(mRealmListener);
    // グローバル変数の取得、入力
    GlobalArrayList= (TaskApp) this.getApplication();
    GlobalArrayList.GlobalArrayList();
    for (int i = 0; i < mCategoryRealmResults.size(); i++) {
        GlobalArrayList.add(mRealmResults.get(i).getContents());
        }
    
[/code]

しかし最後の「GlobalArrayList.add(～）」の「add」が赤字になってしまいます。グローバル変数のArrayList.addというのは使えないのでしょうか。または、初心者なので、どこか文法が間違えているのでしょうか。


CC BY-SA 3.0
2016-10-30T12:02:48.303
29998
2016-10-31T02:03:37.843
19343
question
android java
グローバル変数としてArrayListを使う


`ThisApp
GlobalArrayList`と定義しているので、`GlobalArrayList.GlobalArrayList.add(mRealmResults.get(i).getContents());`とする必要があります。


CC BY-SA 3.0
2016-10-30T12:11:44.113
29999
2016-10-30T12:11:44.113
3745
29998
answer


## 質問の回答

使用したいArrayListは`ThisApp`クラスの`GlobalArrayList`というインスタンス変数です。  
`ThisApp`のインスタンスは`GlobalArrayList`という変数に代入しています。

したがって、  
`GlobalArrayList.GlobalArrayList.add(mRealmResults.get(i).getContents());`  
とすればいいです。

## 変数名／メソッド名の命名について

`GlobalArrayList`という名前を複数使用しているので混乱しているのだと思います。

[code]

    //グローバルに使用する変数
    public ArrayList<String> GlobalArrayList;
    
[/code]

変数名には何を格納しているのかわかるような名前にすると読みやすくなります。  
ここで何を格納してようとしているのかわかりませんが、RealmResultsのcontentsを格納しているので、例えば`contentsList`のような名前が良いです。

[code]

    //初期化メソッド
    public void GlobalArrayList(){
    
[/code]

初期化メソッドは`init***`という名前にするとわかりやすくなります。

[code]

    // グローバル変数の取得、入力
    GlobalArrayList= (TaskApp) this.getApplication();
    
[/code]

ここで取得しているのはApplicationなので`app`等の名前が良いです。

因みに、Javaでは変数名とメソッド名の先頭は小文字にするのが習慣です。

以上を踏まえてコードを書き直すと次のようになります。

[code]

    public class ThisApp extends Application {
        //グローバルに使用する変数
        public ArrayList<String> contentsList;
        //初期化メソッド
        public void initContentsList(){
            contentsList = new ArrayList<String>();
        }
    
[/code]

[code]

    app = (ThisApp) this.getApplication();
    app.initContentsList();
    for (int i = 0; i < mCategoryRealmResults.size(); i++) {
        app.contentsList.add(mRealmResults.get(i).getContents());
    }
    
[/code]


CC BY-SA 3.0
2016-10-30T22:16:31.920
30001
2016-10-31T00:51:06.223
2016-10-31T00:51:06.223
18862
18862
29998
answer


基本的な回答については @tag1216 さんの回答の通りです。

補足ですが、複数のActivityでの利用を想定しているのであれば、`contentsList`の初期化は可能な限り`Application`クラス（今回では`ThisApp`クラス）の`onCreate()`の中で行うのが安全でしょう。

アプリの規模が大きくなったり仕様の変更があった際、必ずしも`MainActivity`からアプリがスタートするわけではなくなる場合があるからです。（ウィジェットからの起動、外部サービスからのスキーマ起動など）

おそらく`MainActivity`以外は「すでに`contentsList`が初期化されている」前提の実装になるかと思いますので、もし`MainActivity`からアプリがスタートしなかった場合に`initContentsList
()`が実行されず、`contentsList`を使っている行で`NullPointerException`が発生し、アプリが強制終了してしまいます。


CC BY-SA 3.0
2016-10-31T02:03:37.843
30003
2016-10-31T02:03:37.843
18895
29998
answer