안드로이드 앱 개발중입니다
호스팅 서버의 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로 서버에서 값을 먼저 받은 후에 그 값을 사용할수 있을까요?