質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.79%

グローバル変数のArrayにデータが追加出来ない。

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,350

score 26

お世話になっております。Android開発初心者です。

現在制作中のアプリで、グローバル変数であるArrayを使いたいのですが、addでデータの追加が出来ず、困っております。

<AndroidManifest.xml>

     android:name = "beginapp"
<beginapp.java>


     public class beginapp extends Application {

     public ArrayList<Integer> global_arraylist;

     public void setGlobal_arraylist() {
          global_arraylist = new ArrayList<Integer>();
    }

}
<該当クラスのコード>

     beginapp nread = new beginapp();

     nread.global_arraylist = new ArrayList<Integer>();

     nread.global_arraylist.add(global_id);

こちらのグローバル変数のArrayListであるglobal_arraylistに、↑
addでデータの追加がされておらず、その為、このArrayを読む際に、"IndexOutOfException"が発生しております。

原因と解決につきまして、お解りでいらっしゃいましたら、ご教授の程、宜しくお願い申し上げます。


2019/10/18  PM12:36

ログで、

Failed sending reply to debugger: Broken pipe.

こちらのエラーも出ておりまして、Clean Projectやキャッシュの削除、リビルドなども致しましたが、未だ解決しておりません、、。


2019/10/18   PM1:22

テストを進めますと、global_idの値は増えますが、やはり、global_arraylistへのデータの追加自体が出来ていないです。


2019/10/18   PM6:37

IndexOutOfExceptionが発生している原因と致しまして、初期データがintで0であることが起因しているのではないか、と思いまして、

ArrayListをIntegerで使用しておりましたが、ArrayListをStringにして、試してみようと思います。


2019/10/18   PM7:05

やっぱりダメです、どうしても、global_arraylistにaddされません。


2019/10/19  AM0:37

ご教授、誠にありがとうございます。

■1点目

     beginapp nread = (beginapp) getApplication();

     nread.global_arraylist = new ArrayList<String>();

     receive2_st = nread.global_arraylist.get(get_id2);

get_id2は、リストビューをタップした際の場所のidです。そして、receive2_stは、ArrayListの変更後のidです。

何をしたいかと申し上げますと、リストビューで項目削除を致しました際に、削除項目を詰めたidの値を割り出したい次第です。Arrayの項目削除時に自動的に削除項目の後ろのデータを詰める性質を利用して、idの空白をなくすようにしたいです。

こちらのコードは、関数にしておりましたが、関数からグローバル変数が呼べなかった為に、処理のコードに埋め込みました。

■2点目

2019-10-19 00:54:27.706 19017-19017//*丙プロジェクト名*/ E/AndroidRuntime: FATAL EXCEPTION: main
Process: /*丙プロジェクト名*//*丙プロジェクト名*/, PID: 19017
java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.get(ArrayList.java:437)
at /*丙プロジェクト・クラス名前*/$2.onItemClick(/*クラス名*/.java:222)
at android.widget.AdapterView.performItemClick(AdapterView.java:318)
at android.widget.AbsListView.performItemClick(AbsListView.java:1252)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3221)
at android.widget.AbsListView$3.run(AbsListView.java:4207)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:251)
at android.app.ActivityThread.main(ActivityThread.java:6563)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

■3点目

ログにもございますように、Arrayのサイズがゼロでしたので、「データの追加自体が出来ていない」と思いました。

■4点目

マークダウンの方法がやっと解かりました。誠にありがとうございます。

◆以下は修正後のコードです。

<beginapp.java>

import java.util.ArrayList;

public class beginapp extends Application {

    public ArrayList<String> global_arraylist;

        public void setGlobal_arraylist() {
        global_arraylist = new ArrayList<String>();
    }

}


<データ投入部分コード>

     beginapp nread = (beginapp) getApplication();

     nread.setGlobal_arraylist();

     nread.global_arraylist.add(string_id);

<string_idの経路>

     boolean next = c2.moveToFirst();
          global_id = c2.getInt(0);
          string_id = String.valueOf(global_id);

本当にありがとうございます。宜しくお願い申し上げます。


2019/10/19   AM11:30

ご報告が漏れておりましたが、global変数のArrayの他に、リストビューでArrayAdapterを使用し、データベースと繋げております。

只今、原因につきまして、自分でも調べさせて頂いております。


2019/10/19   PM4:27

申し訳ありません、質問です。

Global変数の寿命は、Applicationとほぼ、同じでしょうか…?

そして、Global変数として、ArrayListを使いたい、と、申し上げましたが、Global変数であるArrayListの中身は、Applicationが終了すると、無くなってしまいますでしょうか…?

もし、アプリ起動の度に、Global変数のArrayListのデータも0になってしまうのでしたら、私は、全く無意味なことをしようとしておりました。

貴重なお時間を頂いたにも関わらず、本当に申し訳ありません、m(__)m!!

別の方法と致しまして、別のデータベーステーブルを使い、idを管理することを考えております。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • rubytomato

    2019/10/18 21:31

    下記の点についてご確認頂き、適宜質問内容の編集・追記をお願いします。

    > addでデータの追加がされておらず、その為、このArrayを読む際に、"IndexOutOfException"が発生しております。

    ■1点目
    「Arrayを読む際に」とありますが、この部分のコードを質問内容を編集して追記してください。

    ■2点目
    「"IndexOutOfException"が発生して」とありますが、例外が発生したときのエラー全文、上記同様に追記してください。

    > global_arraylistへのデータの追加自体が出来ていないです。

    ■3点目
    「データの追加自体が出来ていない」とのことですが、データが追加できていないことをどのような方法で確認したのか追記してください。

    ■4点目
    すでに何人かの方から指摘されていますが、プログラムコードはコードの前後を3つのバッククォートで囲ってください。こうするとコードが整形されて表示されるので読みやすくなります。
    下記は一例です。
    ちなみにバッククォートはキーボードの"@"がプリントされているキーをShiftキーと同時に押すと入力できます。(Windowsの場合)

    ```
    プログラムコード
    プログラムコード
    プログラムコード
    ```

    キャンセル

  • swordone

    2019/10/19 01:39

    「修正後のコード」が全く修正されてない件

    キャンセル

  • EveryoneCanEat

    2019/10/19 01:45

    修正後のコードを元に戻して手を加えました。


    修正後のコードも上手く動かず、staticを動的に操作するのはまずいのではないか、と思いまして、

    海外のサイトを参考に、コードを書き直しました。

    キャンセル

回答 3

+1

本質問は既に閉じてしまいましたが、以下の点についてだけ回答させていただきます。

Global変数の寿命
Global変数の寿命は、Applicationとほぼ、同じでしょうか…?
...
そして、Global変数として、ArrayListを使いたい、と、申し上げましたが、Global変数であるArrayListの中身は、Applicationが終了すると、無くなってしまいますでしょうか…?

恐らく実質的にApplicationと寿命は同じでしょうが、それを前提としたプログラミングをしてはいけません。ここでいうグローバル変数はJavaのクラス内でのインスタンス変数であり、Applicaitionクラスのインスタンスの寿命は、Androidのシステムとプログラミングに依存した話で、別物です。

ただ、共通して言えることは、どちらも所詮「メモリー」内に存在しているもので、アプリケーションが終了し、アプリケーションが占有していたメモリーが解放されれば、グローバル変数の領域も値も、消滅します。

Applicationクラスを継承したクラスを使うときは、そのコンストラクター内で初期化処理を行うというよりは、Applicationクラス、ひいてはそのアプリケーション自身のライフサイクルを意識する必要があります。これはAndroidプログラミング固有の事情です。アプリケーションが動いているときにプログラマーが作成、編集したデータは、別途オーバーライドしたApplication#onCreateApplication#onTerminateが呼ばれたときにプログラマー自身が必要に応じてファイルやデータベースから値をロードしたり、保存したりしなければなりません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/19 17:53

    ご教授、誠にありがとうございます。

    非常にためになりました。

    AndroidのActivityのライフサイクルにつきまして、本で一通りは勉強させて頂きましたが、完全には、理解出来ておりませんでした。

    ただ、今回のご教授により、見えてきそうです。

    ライフサイクルを把握しないと、メモリリークなどの危険がある、と、勉強させて頂きましたが、

    そのActivityやApplicationの寿命のタイミング、そして、Activityのライフサイクルにおきまして、まだまだ勉強と経験が必要です。

    再三に渡りますご教授、誠に感謝申し上げます、

    本当にありがとうございます。

    キャンセル

checkベストアンサー

0

質問内容の追記ありがとうございました。
はじめにお断りさせて頂きますがAndroidアプリの開発は未経験なので、間違った内容で回答しているかもしれませんがその場合はご容赦ください。
なので以下は直接の回答というよりも、参考程度の内容になっております。

どこに原因があるのか問題の切り分けを行うために、以下のようにコードを修正してログを出力するようにしてください。
ログから実装したコードが想定通りの動きをしているか確認してください。

データ投入部分
beginapp nread = (beginapp) getApplication();

// 1) オブジェクトのIDをログ出力するコードを追加
// たとえば以下のよう
System.out.println(System.identityHashCode(nread));

nread.setGlobal_arraylist();

// 7) このコードをメソッド呼び出しに変更
//nread.global_arraylist.add(string_id);
nread.addId(string_id);
データ取得部分
beginapp nread = (beginapp) getApplication();

// 2) オブジェクトのIDをログ出力するコードを追加
// たとえば以下のよう
System.out.println(System.identityHashCode(nread));

// 3) ※
nread.global_arraylist = new ArrayList<String>();

// 10) このコードをメソッド呼び出しに変更
//receive2_st = nread.global_arraylist.get(get_id2);
receive2_st = nread.getId(get_id2);
beginappの修正
public class beginapp extends Application {

    public ArrayList<String> global_arraylist;

    public void setGlobal_arraylist() {
        global_arraylist = new ArrayList<String>();
        // 4) ここにログ出力するコードを追加
        // たとえば以下のよう
        System.out.println("call setGlobal_arrayList at : " + (new Date()).toString());
    }

    // 5) メソッドを追加
    public void addId(String string_id) {
        global_arraylist.add(string_id);
        // 6) ここにログ出力するコードを追加
        // たとえば以下のよう
        System.out.println("add id:" + string_id);
    }

    // 8) メソッドを追加
    public String getId(String get_id2) {
        String string_id = global_arraylist.get(get_id2);
        // 9) ここにログ出力するコードを追加
        // たとえば以下のよう
        System.out.println("get id:" + string_id);
        return string_id;
    }
}

1) , 2) のコード
System.identityHashCodeはオブジェクトのIDを返します。これをコンソールかログファイルへ出力するようにしてください。
Androidアプリでどうするのが一般的なのかわからなかったので、仮にSystem.out.printlnを使っていますが適切な方法に変えてください。

1)と2)で出力されるIDが一致していれば同一のオブジェクトとみることができます。逆に違うIDだった場合は、想定していないオブジェクトの生成が行われていると思います。なのでglobal_arraylistはクリアされているのではないでしょうか

 3)のコード
疑問なのですが、このコードは必要なのでしょうか?
getするまえにnew ArrayList<String>();を実行するとglobal_arraylistはリセットされてしまうと思います。

 4)のコード
setGlobal_arraylist()にログ出力を行うコードを追加してください。
アプリケーション実行時にこのメソッドがどのタイミングで何回実行されるのか確認し、それが期待通りかどうか確認してください。
複数回呼ばれているのであれば、その都度global_arraylistはリセットされていることになります。

 5), 6)のコード
global_arraylistへの要素追加をメソッドにし、且つログ出力を行うコードを追加します。

 7)のコード
データ投入を上記のメソッドを使うようにします。
アプリケーション実行時にこのメソッドがどのタイミングで何回実行されているのか確認します。

 8), 9)のコード
global_arraylistからの要素取得をメソッドにし、且つログ出力を行うコードを追加します。

 10)のコード
データ取得を上記のメソッドを使うようにします。
アプリケーション実行時にこのメソッドがどのタイミングで何回実行されているのか確認します。

以上の修正後、アプリケーションを実行してみてglobal_arraylistの初期化、データの投入、取得のタイミング、実行回数が期待通りかどうか確認してみてください。

idの投入と取得の考え方

ちょっと気になったので確認させてください。
idの投入と取得を以下のようなコードで行おうとされているのであれば、期待通りに動かないとおもいます。

List<Integer> global_arraylist = new ArrayList<>();

Integer id = 9;

global_arraylist.add(id);  // id=9 を追加

global_arraylist.get(id);  // id=9 を取得

getメソッドの引数は取得したい値でなく、取得したい要素の位置(position)を指定します。
なので、id9の要素を取得するにはget(0)のように0番目の位置を指定しなければなりません。

global_arraylist.add(id);  // index 0 に要素を追加

global_arraylist.get(id);  // index 9 の要素を取得
                           // index 9 に要素はないので java.lang.IndexOutOfBoundsException がスローされる
Global変数の寿命

Global変数の寿命は、Applicationとほぼ、同じでしょうか…?

そして、Global変数として、ArrayListを使いたい、と、申し上げましたが、Global変数であるArrayListの中身は、Applicationが終了すると、無くなってしまいますでしょうか…?

冒頭でも言いましたがAndroidアプリケーションについては無知なので、なんとも言えませんがアプリケーションが終了したらインスタンスもメモリから消えるのが一般的ではないかと思います。

こちらは専門の方の回答をお待ちなってください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/19 16:45

    本当に貴重なお時間と労力、温かいお心遣い、本当にありがとうございます。

    初心者である私目に、解りやすいご教授、お心遣い、恐縮致します。

    私の頭の中で、繋がっていなかった部分におきまして、しっかりコードを読み、咀嚼致しまして、レベルアップの為、精進させて頂きます。

    言葉になりません。本当にありがとうございます。

    キャンセル

0

そもそもの大前提として、このglobal_arraylistはグローバル変数になっていません。
Applicationを継承したからと言って、アプリ内の共通変数になるということはありません。このextends Applicationは全くの無駄です。
この変数を参照しようとする際に、その参照しようとする場所でnew beginapp()すると思うのですが、そこで得たbeginappは「該当クラスのコード」で使ったbeginappとは別物になります。

やるとしたらglobal_arraylistをstaticにすることになりますが、確かこれ、あまり褒められたやり方じゃなかったような気が…

//クラス名は大文字始まりで
public class BeginApp {

    static public ArrayList<Integer> global_arraylist;

    // これいる?
    public static void setGlobal_arraylist() {
        global_arraylist = new ArrayList<Integer>();
    }

}

// 必要な個所で
BeginApp.global_arraylist = new ArrayList<Integer>();

BeginApp.global_arraylist.add(global_id);

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/18 12:02

    警告はどのようにすれば宜しいでしょうか…?

    キャンセル

  • 2019/10/18 12:11

    申し訳ありませんでした。直ぐにRunしてみます。

    キャンセル

  • 2019/10/18 12:14

    Runしましたが、未だIndexOutOfExceptionが出ております。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.79%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る