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

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

ただいまの
回答率

88.09%

オーバライドされた、voidメソッドから戻り値を取りたいです。

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,151

score 409

前提・実現したいこと

フラグメントを使用したいです。
setListAdapterの第三引数にJSONデータを取得するメソッドを起きましたが、
そのメソッドはvoid型で、スコープの関係上戻り値を取得できないことに気がつきました。

※第三引数自体にあるメソッド自体は戻り値があります。そのメソッドの中にvoid型メソッドがあり、そのメソッドはオーバライドされたものです。

発生している問題・エラーメッセージ

ターミナル

06-02 10:31:19.326 7854-7854/station.around.aroundsatation I/System.out: あ
06-02 10:31:19.326 7854-7854/station.around.aroundsatation I/System.out: [] ★戻り値(スコープで空になってしまう。)★
06-02 10:31:19.326 7854-7854/station.around.aroundsatation I/System.out: い

該当のソースコード

public class HttpConnect {

    public List<String> lists = new ArrayList<String>(); ★①

    public List<String> showMember(){★②戻り値があるメソッド
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://candii.tk/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        ImageClient service = retrofit.create(ImageClient.class);


        Call<List<ListImage>> call2 = service.listImages();
        System.out.println(service.listImages());

        call2.enqueue(new Callback<List<ListImage>>() {
            @Override
            public void onResponse(Call<List<ListImage>> call, Response<List<ListImage>> response) { ★③戻り値がないメソッド
                List<ListImage> listImage = response.body();
                System.out.println(response.body());
                int s = listImage.size();


                for(int i = 0; i < s; i++){
                    Log.d("debug3", listImage.get(i).toString());
                    System.out.println(listImage.get(i).getEn_title());
                    lists.add(listImage.get(i).getEn_title());
                }

            }

            @Override
            public void onFailure(Call<List<ListImage>> call, Throwable t) {
                Log.d("debug4", t.getMessage());
            }
        });
        System.out.println("あ");
        System.out.println(lists); ★④空になる。
        System.out.println("い");
        return lists;
    }

}

Retrofit2を使っています。
③のメソッドを戻り値ありに変更できず、結果①で定義した変数に③で取得した配列を格納できず、
②メソッドの戻り値が空になります。

③から②へ値を渡す方法に関してご助言をいただきたいです!

ちなみにフラグメントはこのような形で行ってます。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //リストフラグメントの生成(2)
    public static class TitlesFragment extends ListFragment {
        private int pos = -1;
        public HttpConnect hc = new HttpConnect();

        //アクティビティ生成完了時に呼ばれる(3)
        @Override
        public void onActivityCreated(Bundle bundle) {
            super.onActivityCreated(bundle);
            setListAdapter(new ArrayAdapter<String>(getActivity(),
                    android.R.layout.simple_list_item_activated_1,
                    (List<String>)hc.showMember())); ★★
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            getListView().setBackgroundColor(Color.LTGRAY);
            if (isTablet(getActivity())) showDetails(0);
        }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

よろしくお願いします。

 追加

以下の記事のようにonResponseメソッド内でViewに値を設定するのが良いのでしょうか。
ただ、以下のやり方だとフラグメントは使えなさそうな木がするのですが、

Android:Retrofit2.0ではてなAPIとおしゃべりしてみた

それともセッターを作った方がいいんでしょうか。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+2

戻り値がvoidのメソッドではどうやっても戻り値を返すことはできません。
そのため③から②に値を渡すという考え方自体が間違っています。

・コールバックインターフェースを自作する。
・フラグメントで上記のインターフェースを実装する。
・HttpConnectに上記のインターフェースをコールバックインターフェースとして設定する。
・onResponseてコールバックメソッドを呼び、フラグメントにlistsを渡す。

また、表示処理が無いのにshowMemberというメソッド名はイマイチですね。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/06/02 15:59

    ありがとうございます!
    試してみます!

    コールバックあまり経験ないのでお時間いただきます!

    キャンセル

+1

Androidでは通信等の思い処理は別スレッドで行わなければなりません。
Retrofitもそれに則っており通信処理は別スレッドで行っています。
今回戻り値が空の配列になってしまうのは、別スレッドで行われている通信処理の完了を待たないでreturnしてしまっているからです。

僕が考え付く解決策としては
・showMemberの戻り値をCallback<List<ListImage>>にしてfragment側で通信結果を受け取ってviewにデータをせっとする
・showMemberの引数にviewを渡して通信が終わったらviewにデータをせっとする
・コールバックインターフェースを作成し、通信結果をfragmentにコールバックする

があります。2番目の方法はメモリリークの可能性があるのであまりおすすめ出来ません。一番簡単なのは1番目の方法だと思います

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/06/02 15:54 編集

    ありがとうございます!
    すみません。1番目の方法ですが、
    public List<ListImage> showMember(){  〜〜  return Callback<List<ListImage>>;}}
    こういうことですか?

    キャンセル

  • 2017/06/02 16:24

    すみません。戻り値ではなく、戻り値の型でした。
    public List<ListImage> showMember()→public Callback<List<ListImage>> showMember()へ変更してください

    キャンセル

  • 2017/06/02 17:54

    ありがとうございます!
    戻り値でエラーが出るので、調整します!

    キャンセル

0

お二人の意見を元に解決できました。

かなり強引に行きました。

解決してはいますが、ご意見頂けますと嬉しいです。

Present.javaのフラグメントのリストを表示する処理をメソッド化し、
そのメソッドをコールバック関数内に仕込みました。

実現した流れは以下です。

①JSON配列データリスト表示メソッド起動(Present.java#setListAdapterMethod)
②HTTP通信&JSONデータ取得(HttpConnect.java#passList)
③JSONデータ取得後にコールバック関数の起動(Present.java#callbackMethod)
④コールバック関数内でもう一度配列データリスト表示メソッド起動(Present.java#callbackMethod#setListAdapterMethod)

setListAdapterMethodを新しく作り解決できました。

Before

            setListAdapter(new ArrayAdapter<String>(getActivity(),
                    android.R.layout.simple_list_item_activated_1,
                    lists));
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            getListView().setBackgroundColor(Color.LTGRAY);
            if (isTablet(getActivity())) showDetails(0);

After

        public void setListAdapterMethod(List<String> lists){
            System.out.println(lists);
            setListAdapter(new ArrayAdapter<String>(getActivity(),
                    android.R.layout.simple_list_item_activated_1,
                    lists));
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            getListView().setBackgroundColor(Color.LTGRAY);
            if (isTablet(getActivity())) showDetails(0);
        }

★以下全コード★

Present.java

public class Present extends Activity {

 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

    //リストフラグメントの生成(2)
    public static class TitlesFragment extends ListFragment implements CallHttp.CallHttpCallbacks {

 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

        //アクティビティ生成完了時に呼ばれる(3)
        @Override
        public void onActivityCreated(Bundle bundle) {
            super.onActivityCreated(bundle);

            hc.passList();
            System.out.println("あああ");
            System.out.println(lists);
            System.out.println("いいい");
            setListAdapterMethod(lists); ★メソッド化★
        }

 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜


        public void callbackMethod(List<String> lists){
            System.out.println( "コールバック成功!");
            System.out.println(lists);
            setListAdapterMethod(lists); ★メソッド追加★
        }


        public void setListAdapterMethod(List<String> lists){ ★メソッド化★
            System.out.println(lists);
            setListAdapter(new ArrayAdapter<String>(getActivity(),
                    android.R.layout.simple_list_item_activated_1,
                    lists));
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            getListView().setBackgroundColor(Color.LTGRAY);
            if (isTablet(getActivity())) showDetails(0);
        }
    }


}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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