프래그먼트의 onCreateView 내에서 실행했을때와 멤버함수에서 실행했을때 실행되고 안되고 차이가 있어 질문좀 드립니다.
pager.setOffscreenPageLimit(items.size());
문제의 코드는 이것이고
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.bstcproject, PID: 24791
java.lang.IllegalArgumentException: Offscreen page limit must be OFFSCREEN_PAGE_LIMIT_DEFAULT or a number > 0
at androidx.viewpager2.widget.ViewPager2.setOffscreenPageLimit(ViewPager2.java:833)
at com.example.bstcproject.MovieFragment.onCreateView(MovieFragment.java:125)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224)
대충 이러한 에러가 납니다
프래그먼트의 onCreateView입니다.
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final ViewGroup rootView =(ViewGroup) inflater.inflate(R.layout.fragment_movie, container, false);
items = new ArrayList<>();
pager = rootView.findViewById(R.id.pager);
adpater = new MovieListAdapter();
// 서버큐 연결
if (AppHelper.requestQueue == null) {
AppHelper.requestQueue = Volley.newRequestQueue(getContext());
}
requestMovieList(); // 서버요청하기
pager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
pager.setAdapter(adpater);
// 뷰페이저 좌우 프리뷰 구현1
pager.setClipToPadding(false);
pager.setClipChildren(false);
pager.setOffscreenPageLimit(items.size()); pager.getChildAt(0).setOverScrollMode(RecyclerView.OVER_SCROLL_NEVER);
// 뷰페이저 좌우 프리뷰 구현2
CompositePageTransformer compositePageTransformer = new CompositePageTransformer();
compositePageTransformer.addTransformer(new MarginPageTransformer(0));
// 페이지 넘기는 애니메이션? 같은 효과를 주는 코드인듯
compositePageTransformer.addTransformer(new ViewPager2.PageTransformer() {
@Override
public void transformPage(@NonNull View page, float position) {
float r = 1 - Math.abs(position);
page.setScaleY(0.85f + r * 0.15f);
}
});
pager.setPageTransformer(compositePageTransformer);
return rootView;
}
해당 코드가 onCreateView의 해당 위치에 있을때 에러가나고,
// 요청 객체만들기
public void requestMovieList() {
// http://boostcourse-appapi.connect.or.kr:10000/movie/readMovieList?type=1
String url = "http://" + AppHelper.host + ":"+ AppHelper.port + "/movie/readMovieList";
url += "?" + "type=" + 1; // 요청 파라미터
//요청객체
StringRequest request = new StringRequest(
Request.Method.GET,
url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// 요청 보내고 정상 응답을 받는곳
println(response);
processResponse(response); // gson으로 파싱하기
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// 에러 발생시 호출 됨
println("에러 발생 : " + error );
}
}
);
request.setShouldCache(false);
AppHelper.requestQueue.add(request); // 요청큐에 요청객체 넣기
}
// 받아온 응답 gson으로 자바 객체화 (파싱)
public void processResponse(String response) {
Gson gson = new Gson();
ResponseInfo info = gson.fromJson(response, ResponseInfo.class);
if(info.code == 200) {
movie = gson.fromJson(response, Movie.class);
// MovieInfo 정보를 하나씩 꺼내와 ArrayList에 추가
for(int i=0; i<movie.result.size(); i++) {
mvmitem = movie.result.get(i);
items.add(mvmitem);
}
adpater.setItems(items); // ArrayList<MovieModel>을 통째로 전달
adpater.notifyDataSetChanged();
// pager.setOffscreenPageLimit(items.size());
}
}
processResponse 메소드 안의 주석처리된곳에서 실행하면 정상작동 됩니다.
그런데 이것도 파라미터로 items.size()를 줬을때 얘기고
onCreateView에서 실행해도 파라미터로 그냥 int 값인 뭐 3이나 4 등등을 줬을때는 정상작동 합니다.
하지만 무작정 int값을 주기보다는 ArrayLits의 아이템사이즈에 맞춰서 주고싶어서 저렇게 넣었습니다.
같은코드인데
onCreateView에서 순서를 보시면 제가 기대하기를
그냥 코드 순서대로 위에서 아래로 순차적으로 실행되기를 기대했습니다
requestMovieList()가 호출되고 그안에서 이제 콜백메소드안에서 processResponse()가 호출됩니다.
이후에 processResponse()내의 코드를 순차적으로 실행되고 종료되고 requestMovieList()도 종료되고
이제 남은 onCreateView()내의 requestMovieList()이후의 코드들을 순차실행 되기를 기대했는데
그렇지 않은것 같습니다...

코드를 대거 변경하기 전 코드인데, 이때는 코드가 저위치에 있는데도 실행이 됐습니다
그런데 지금 processResponse함수내로 들어갔을때는 되고 지금은 안되는걸보면
requestMovieList()를 호출하고 함수내에서 processResponse() 호출할때 이 함수가 끝나기전에
혹시 onCreateView() 에서 나머지 코드가 실행돼서 그런것 아닌가하는생각이 들기때문입니다..
이게 가능한가요? 원래 제 어줍짢은 지식으로는
함수를 호출해서 진입하면 함수가 다끝나고 다음 코드가 실행되는것 아닌가요?
이렇게 함수가 진행되고 있는데 다음코드가 진행되고 그런건 스레드가 여러개 일때나 막 그렇게 실행되는
것 아닌가요?..제 코드는 스레드를 따로 만들지 않았고 메인스레드 하나에서 진행되는 것일텐데..
그래서 제가 추측하기로는
onCreateView()에서 setOffscreenPageLimit() 실행했을시 -> onCreateView에서 나머지 코드가 실행되어 processResponse가 끝나기전에 setOffscreenPageLimit()가 실행되어 에러가 난다.
processResponse() 내에서 setOffscreenPageLimit() 실행했을시 -> processResponse내에서 setItems()까지 다 끝내고 나서야 setOffscreenPageLimit()이 실행되므로 onCreateView()가 진행을 해도 에러가 나지않는다.
같은데.. 제가 생각한 추측이 맞나요..? 순차적으로 함수가 다끝나고 실행되는것이아니라
함수가 호출되고 있는 와중에도 무시하고 onCreateView()내에서 막 다음 코드가 진행되고 그런건가요..?
아니면 혹시 또다른 이유가 있을까요?