마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

volley onResponse 호출때까지 대기 후 다음코드 실행하는 방법에 대해

0 추천

안드로이드 앱 개발중입니다

 

호스팅 서버의 DB에 json 형식의 데이터들이 저장되어있고 

안드로이드 스튜디오의 Volley RequestQueue queue.add 를 통해서 

 

서버 DB - php - Volley 라이브러리의 onResponse로 서버의 json 데이터들을 받아옵니다.

        Response.Listener<String> responseListener2 = new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {

                try {
                    JSONArray jsonArray = new JSONArray(response);

                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        JSONObject a = jsonObject.getJSONObject("Book");

                        String fileName = a.getString("fileName");

                        Thread t = new ImageThread(fileName);
                        t.start();

                        t.join();

                        SellBookDB sellBookDB = new SellBookDB(bitmap,a.getString("bookName"),a.getString("bookName"),a.getString("bookName"),a.getString("bookName"),a.getString("bookName"),a.getString("bookName"),a.getString("bookName"),a.getString("bookName"));

                        arrayList.add(sellBookDB);
                    }
                } catch (Exception e) {

                }
            }
        };

        SellBoardListRequest sellBoardListRequest = new SellBoardListRequest(responseListener2);
        RequestQueue queue1 = Volley.newRequestQueue(getActivity());
        queue1.add(sellBoardListRequest);

 

디버깅을 통해서 값들이 서버DB에서 무사히 넘어와서 arrayList에 저장되는것까지 확인을 했습니다.

 

그리고 이제 arrayList에 저장된 결과들을 listview를 통해서 게시판 형식의 느낌으로 출력하고자 하는데 여기서 문제가 발생합니다

 

커스텀 리스트뷰를 만들고 adapter.addItem(); 을 사용해서 리스트뷰에 가져온 결과값을 출력하고자 하는데

 

아무리 해도 함수들의 호출 순서가 onResponse가 마지막이 됩니다.

 

그러니까 코드를 어떤 순서로 놓던간에 adapter.addiItem이 먼저 호출되서 arrayList에는 아직 서버에서 값을 불러오지 않은 빈 List가 들어가게되고

 

코드의 모든 내용들이 실행되고나서야 마지막에 onResponse가 실행되어서 서버에서 값을 불러옵니다.

 

제 생각에는 

1. onResponse가 먼저 호출되어서 서버에서 값을 가져오고

2. 그 값을 이용해서 arrayList.length만큼 반복문으로 리스트뷰에 값들을 추가시키는것이 맞다고 생각하는데

3. onResponse가 항상 가장 마지막에 실행되는 문제입니다.

 

 

현재 배우면서 만드는중이라 코드가 매우 지저분한 상태이긴 한데 전체 코드를 올리겠습니다.

public class SellFragment extends Fragment {

    Button btn;

    Bitmap bitmap;
    BitmapDrawable bdrawable;
    ListViewAdapter adapter = new ListViewAdapter();
    private boolean mLockListView = false;
    private LayoutInflater mInflater;

    ArrayList<SellBookDB> arrayList = new ArrayList<>();


    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        sendRequest();


        adapter.notifyDataSetChanged();

        View view = inflater.inflate(R.layout.fragment_sell, null);
        mLockListView = true;
        ListView listView = view.findViewById(R.id.listview1);

        listView.setAdapter(adapter);
        btn = (Button)view.findViewById(R.id.button2);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getActivity(),AddBoardActivity.class);
                startActivity(intent);
            }
        });

        listView.setOnScrollListener(new AbsListView.OnScrollListener() {

            public void onScrollStateChanged(AbsListView view, int scrollState) {


            }

            public void onScroll(AbsListView view, int firstVisibleItem,
                                 int visibleItemCount, int totalItemCount) {

                if(firstVisibleItem+visibleItemCount == totalItemCount && totalItemCount!=0)
                {
                    if(mLockListView == false)
                    {
                        for (int i = totalItemCount; i < totalItemCount + 6; i++) {

                            SellBookDB sellBookDB = arrayList.get(i);

                            Bitmap b = sellBookDB.getBookCover();
                            String ccc = sellBookDB.getBookname();
                            String ddd = sellBookDB.getBookprice();

                            adapter.addItem(b, ccc, ddd);
                        }
                        adapter.notifyDataSetChanged();
                    }
                }

                else if(totalItemCount ==0){

                    for (int i =0; i<6;i++) {

                        SellBookDB sellBookDB = arrayList.get(i);

                        Bitmap b = sellBookDB.getBookCover();
                        String ccc = sellBookDB.getBookname();
                        String ddd = sellBookDB.getBookprice();

                        adapter.addItem(b, ccc, ddd);

                    }

                }
            }
        });

        return view;





    }

    public void sendRequest(){

        Response.Listener<String> responseListener2 = new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {

                try {
                    JSONArray jsonArray = new JSONArray(response);

                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        JSONObject a = jsonObject.getJSONObject("Book");

                        String fileName = a.getString("fileName");

                        Thread t = new ImageThread(fileName);
                        t.start();

                        t.join();

                        SellBookDB sellBookDB = new SellBookDB(bitmap,a.getString("bookName"),a.getString("bookName"),a.getString("bookName"),a.getString("bookName"),a.getString("bookName"),a.getString("bookName"),a.getString("bookName"),a.getString("bookName"));

                        arrayList.add(sellBookDB);
                    }
                } catch (Exception e) {

                }
            }
        };

        SellBoardListRequest sellBoardListRequest = new SellBoardListRequest(responseListener2);
        RequestQueue queue1 = Volley.newRequestQueue(getActivity());
        queue1.add(sellBoardListRequest);

    }

    public class ImageThread extends Thread {

        String fileName;

        public ImageThread(String tt) {
            this.fileName = tt;
        }

        @Override
        public void run() {
            try {
                URL url = new URL("https://gurwls1307.cafe24.com/" + fileName);
                HttpURLConnection con = (HttpURLConnection) url.openConnection();
                con.setDoInput(true);
                con.connect();

                InputStream is = con.getInputStream();
                bitmap = BitmapFactory.decodeStream(is);
                bdrawable = new BitmapDrawable(getActivity().getResources(), bitmap);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}



 

전체 코드에서 설명드리자면 onCreateView 하자마자 sendRequest 함수를 호출하여 서버에서 값을 불러오고 그 이후에 

                    for (int i =0; i<6;i++) {

                        SellBookDB sellBookDB = arrayList.get(i);

                        Bitmap b = sellBookDB.getBookCover();
                        String ccc = sellBookDB.getBookname();
                        String ddd = sellBookDB.getBookprice();

                        adapter.addItem(b, ccc, ddd);

                    }

를 진행했음에도 불구하고 arrayList에 값이 없어서 바로 앱이 종료되어버립니다.

 

어떻게하면 onResponse로 서버에서 값을 먼저 받은 후에 그 값을 사용할수 있을까요?

tngusrl (120 포인트) 님이 2019년 6월 14일 질문

1개의 답변

0 추천
onResponse후에 list 변경사항에 대해 처리해 줘야 합니다

volley는 비동기므로 위의 코드 순서는 맞지 않습니다

sendRequest()를 한후에 onResponse에서 데이터를 파싱후에 list 업데이트 작업을 해주세요

쉽게말해

1. listview 초기화

2. 서버로 부터 데이터 수신

3. listview 갱신
prague (26,200 포인트) 님이 2019년 6월 14일 답변
...