0

AsyncTaskLoader를 사용하여 API에서 데이터를 가져온 다음 사용자 정의 어댑터를 사용하여 각각 두 개의 RecyclerView를 확장합니다. 문제는 리사이클 뷰를 클릭하여 특정 위치에 대한 detailsActivity로 이동 한 다음 원래 액티비티로 다시 돌아 왔을 때 saveInstanceState가 비어 있음을 발견했습니다. 그러나 장치를 회전 시키면 꽤 잘 돌아갑니다. 나는 이것이 올바른 행동이라고 생각하지 않는다. 그것은 화면 회전과 함께 작동한다면 그것은 내 고민의 경우에도 작동합니다.savedInstanceState onLoadReset 후에 비어 있지만 onCreate가 호출되고 onLoadReset이 아닌 경우 잘 작동합니다 (기기 회전의 경우와 동일).

public class MoviePosterFragment extends Fragment implements LoaderManager.LoaderCallbacks<ArrayList<Movie>> { 

private static final int POPULAR_MOVIE_LOADER_ID = 1111; 
private static final int UPCOMING_MOVIE_LOADER_ID = 9999; 
ArrayList<Movie> popularMovies; 
ArrayList<Movie> upcomingMovies; 
PopularMoviesAdapter mPopularMoviesAdapter; 
UpcomingMovieAdapter mUpcomingMovieAdapter; 
RecyclerView mPopularMovieRecyclerView; 
RecyclerView mUpcomingMovieRecyclerView; 
Uri.Builder uriBuilder; 
String savedInstance; 
LinearLayoutManager layoutManagerPopularMoviesPoster; 
LinearLayoutManager layoutManagerUpcomingMoviesPoster; 

public MoviePosterFragment() { 
    // Required empty public constructor 
} 

@Override 
public void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Log.v("############******", "onCreate called"); 
    if (savedInstanceState == null) { 
     popularMovies = new ArrayList<>(); 
     upcomingMovies = new ArrayList<>(); 
     savedInstance = "empty"; 
     Log.v("############******", "onCreate savedInstance is " + savedInstance); 
     //First of all check if network is connected or not then only start the loader 
     ConnectivityManager connMgr = (ConnectivityManager) 
       getActivity().getSystemService(Context.CONNECTIVITY_SERVICE); 
     NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); 
     if (networkInfo != null && networkInfo.isConnected()) { 
      /* 
      *fetch data. Get a reference to the LoaderManager, in order to interact with loaders. 
      */ 
      Log.v("############******", "startPopularMoviesLoaderManager called"); 
      startPopularMoviesLoaderManager(); 
      Log.v("############******", "startUpcomingMoviesLoaderManager called"); 
      startUpcomingMoviesLoaderManager(); 

     } 

    } else { 
     savedInstance = "not empty"; 
     Log.v("############******", "onCreate savedInstance is " + savedInstance); 
     popularMovies = savedInstanceState.getParcelableArrayList("popularMovies"); 
     upcomingMovies = savedInstanceState.getParcelableArrayList("upcomingMovies"); 

    } 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    Log.v("############******", "onCreateView savedInstance is " + savedInstanceState); 
    // Inflate the layout for this fragment 
    View rootView = inflater.inflate(R.layout.fragment_movie_posters, container, false); 

    /* Code referenced from the @link: 
    * "https://guides.codepath.com/android/using-the-recyclerview" 
    */ 
    /* 
    * Lookup the recyclerView in activity layout 
    */ 
    mPopularMovieRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerViewPopularMovies); 
    mUpcomingMovieRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerViewTopMoviesMovies); 

    /* 
     * Setup layout manager for items with orientation 
     * Also supports `LinearLayoutManager.HORIZONTAL` 
     */ 
    layoutManagerPopularMoviesPoster = new LinearLayoutManager(getActivity(), 
      LinearLayoutManager.HORIZONTAL, false); 
     /* Optionally customize the position you want to default scroll to */ 
    layoutManagerPopularMoviesPoster.scrollToPosition(0); 
     /* Attach layout manager to the RecyclerView */ 
    mPopularMovieRecyclerView.setLayoutManager(layoutManagerPopularMoviesPoster); 

    /* 
     * Setup layout manager for items with orientation 
     * Also supports `LinearLayoutManager.HORIZONTAL` 
     */ 
    layoutManagerUpcomingMoviesPoster = new LinearLayoutManager(getActivity(), 
      LinearLayoutManager.HORIZONTAL, false); 
     /* Optionally customize the position you want to default scroll to */ 
    layoutManagerUpcomingMoviesPoster.scrollToPosition(0); 
     /* Attach layout manager to the RecyclerView */ 
    mUpcomingMovieRecyclerView.setLayoutManager(layoutManagerUpcomingMoviesPoster); 

    SnapHelper snapHelperForPopularMovieRecyclerView = new GravitySnapHelper(Gravity.START); 
    snapHelperForPopularMovieRecyclerView.attachToRecyclerView(mPopularMovieRecyclerView); 

    SnapHelper snapHelperForUpcomingMovieRecyclerView = new GravitySnapHelper(Gravity.START); 
    snapHelperForUpcomingMovieRecyclerView.attachToRecyclerView(mUpcomingMovieRecyclerView); 

    /* Code referenced from the @link: 
    * "https://guides.codepath.com/android/using-the-recyclerview" 
    */ 

    // Create mPopularMoviesAdapter passing in the sample user data 
    mPopularMoviesAdapter = new PopularMoviesAdapter(getActivity(), popularMovies); 
    mPopularMoviesAdapter.setMovieData(popularMovies); 
    // Attach the mPopularMoviesAdapter to the recyclerview to populate items 
    mPopularMovieRecyclerView.setAdapter(mPopularMoviesAdapter); 

    // Create mUpcomingMoviesAdapter passing in the sample user data 
    mUpcomingMovieAdapter = new UpcomingMovieAdapter(getActivity(), upcomingMovies); 
    mUpcomingMovieAdapter.setMovieData(upcomingMovies); 
    // Attach the mUpcomingMoviesAdapter to the recyclerview to populate items 
    mUpcomingMovieRecyclerView.setAdapter(mUpcomingMovieAdapter); 

    return rootView; 
} 

@Override 
public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    Log.v("############******", "onActivityCreated called and saveInstance is " + savedInstanceState); 
    mPopularMoviesAdapter = new PopularMoviesAdapter(getActivity(), popularMovies); 
    mUpcomingMovieAdapter = new UpcomingMovieAdapter(getActivity(), upcomingMovies); 
    mUpcomingMovieAdapter.setMovieData(upcomingMovies); 
    mPopularMoviesAdapter.setMovieData(popularMovies); 
    mPopularMovieRecyclerView.setAdapter(mPopularMoviesAdapter); 
    mUpcomingMovieRecyclerView.setAdapter(mUpcomingMovieAdapter); 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    Log.v("############******", "onSaveInstanceState called"); 
    outState.putParcelableArrayList("popularMovies", popularMovies); 
    outState.putParcelableArrayList("upcomingMovies", upcomingMovies); 
} 


private void startPopularMoviesLoaderManager() { 
    LoaderManager loaderManager = getLoaderManager(); 
    Log.v("############******", "initLoader called with id " + POPULAR_MOVIE_LOADER_ID); 
    loaderManager.initLoader(POPULAR_MOVIE_LOADER_ID, null, this); 
    Log.v("############******", "startPopularMoviesLoaderManager finished"); 
} 

private void startUpcomingMoviesLoaderManager() { 
    LoaderManager loaderManager = getLoaderManager(); 
    Log.v("############******", "initLoader called with id " + UPCOMING_MOVIE_LOADER_ID); 
    loaderManager.initLoader(UPCOMING_MOVIE_LOADER_ID, null, this); 
    Log.v("############******", "startUpcomingMoviesLoaderManager finished"); 
} 

@Override 
public Loader<ArrayList<Movie>> onCreateLoader(int id, Bundle args) { 
    if (id == POPULAR_MOVIE_LOADER_ID) { 
     Log.v("############******", "onCreateLoader called with id " + POPULAR_MOVIE_LOADER_ID); 
     Uri baseUri = Uri.parse(UrlsAndConstants.MoviePosterQuery.DEFAULT_URL); 
     Log.v("############", "baseUri is " + baseUri.toString()); 
     uriBuilder = baseUri.buildUpon(); 
     Log.v("############", "uriBuilder is " + uriBuilder.toString()); 
     uriBuilder.appendQueryParameter(API_KEY_PARAM, API_KEY_PARAM_VALUE); 
     Log.v("############", "uriBuilder.toString() is " + uriBuilder.toString()); 
     uriBuilder.appendQueryParameter(SORT_BY_KEY, SORT_BY_POPULARITY_VALUE_DESCENDING); 

    } else if (id == UPCOMING_MOVIE_LOADER_ID) { 
     Log.v("############", "onCreateLoader called with id " + UPCOMING_MOVIE_LOADER_ID); 
     Uri baseUri = Uri.parse("https://api.themoviedb.org/3/movie/upcoming"); 
     Log.v("############", "baseUri is " + baseUri.toString()); 
     uriBuilder = baseUri.buildUpon(); 
     Log.v("############", "uriBuilder is " + uriBuilder.toString()); 
     uriBuilder.appendQueryParameter(API_KEY_PARAM, API_KEY_PARAM_VALUE); 
     Log.v("############", "uriBuilder.toString() is " + uriBuilder.toString()); 
    } 
    return new MoviePosterLoader(getActivity().getApplicationContext(), uriBuilder.toString()); 
} 

@Override 
public void onLoadFinished(Loader<ArrayList<Movie>> loader, ArrayList<Movie> incomingMovieArrayList) { 
    switch (loader.getId()) { 
     case POPULAR_MOVIE_LOADER_ID: 
      Log.v("############******", "onLoadFinished called with id " + POPULAR_MOVIE_LOADER_ID); 
      if (incomingMovieArrayList.isEmpty()) { 
       Log.v("******************", "popularMovies isEmpty"); 
       return; 
      } else { 
       popularMovies = incomingMovieArrayList; 
       mPopularMoviesAdapter = new PopularMoviesAdapter(getActivity(), popularMovies); 
       mPopularMoviesAdapter.setMovieData(popularMovies); 
       mPopularMovieRecyclerView.setAdapter(mPopularMoviesAdapter); 

      } 
      break; 
     case UPCOMING_MOVIE_LOADER_ID: 
      Log.v("############******", "onLoadFinished called with id " + UPCOMING_MOVIE_LOADER_ID); 
      if (incomingMovieArrayList.isEmpty()) { 
       Log.v("******************", "popularMovies isEmpty"); 
       return; 
      } else { 
       upcomingMovies = incomingMovieArrayList; 
       mUpcomingMovieAdapter = new UpcomingMovieAdapter(getActivity(), upcomingMovies); 
       mUpcomingMovieAdapter.setMovieData(upcomingMovies); 
       mUpcomingMovieRecyclerView.setAdapter(mUpcomingMovieAdapter); 
      } 
      break; 
    } 
} 

@Override 
public void onLoaderReset(Loader<ArrayList<Movie>> loader) { 
    Log.v("############******", "onLoaderReset called "); 

} 

}

그리고 아래의 로그 캣 메시지에서 볼 수 있듯이이 문제가 확실히있다 :

여기 내 조각의 코드입니다.

로그 캣 메시지 :

`응용 프로그램은 처음 시작할 때 :

12-07 01:37:56.450 9756-9756/me.abhishekraj.showmyshow V/############******: onCreate called 
12-07 01:37:56.450 9756-9756/me.abhishekraj.showmyshow V/############******: onCreate savedInstance is empty 
12-07 01:37:56.450 9756-9756/me.abhishekraj.showmyshow V/############******: startPopularMoviesLoaderManager called 
12-07 01:37:56.453 9756-9756/me.abhishekraj.showmyshow V/############******: initLoader called with id 1111 
12-07 01:37:56.453 9756-9756/me.abhishekraj.showmyshow V/############******: onCreateLoader called with id 1111 
12-07 01:37:56.455 9756-9756/me.abhishekraj.showmyshow V/############******: startPopularMoviesLoaderManager finished 
12-07 01:37:56.455 9756-9756/me.abhishekraj.showmyshow V/############******: startUpcomingMoviesLoaderManager called 
12-07 01:37:56.455 9756-9756/me.abhishekraj.showmyshow V/############******: initLoader called with id 9999 
12-07 01:37:56.455 9756-9756/me.abhishekraj.showmyshow V/############******: startUpcomingMoviesLoaderManager finished 
12-07 01:37:56.456 9756-9756/me.abhishekraj.showmyshow V/############******: onCreateView savedInstance is null 
12-07 01:37:56.493 9756-9756/me.abhishekraj.showmyshow V/############******: onActivityCreated called and saveInstance is null 
12-07 01:37:57.683 9756-9756/me.abhishekraj.showmyshow V/############******: onLoadFinished called with id 9999 
12-07 01:37:57.731 9756-9756/me.abhishekraj.showmyshow V/############******: onLoadFinished called with id 1111 
After a popular movie poster is clicked 
12-07 01:29:16.062 2256-2256/me.abhishekraj.showmyshow V/############******: onSaveInstanceState called 
After coming back from DetailActivity 
12-07 01:38:52.785 9756-9756/me.abhishekraj.showmyshow V/############******: onLoaderReset called 
12-07 01:38:52.785 9756-9756/me.abhishekraj.showmyshow V/############******: onLoaderReset called 
12-07 01:38:52.851 9756-9756/me.abhishekraj.showmyshow V/############******: onCreate called 
12-07 01:38:52.851 9756-9756/me.abhishekraj.showmyshow V/############******: onCreate savedInstance is empty 
12-07 01:38:52.851 9756-9756/me.abhishekraj.showmyshow V/############******: startPopularMoviesLoaderManager called 
12-07 01:38:52.851 9756-9756/me.abhishekraj.showmyshow V/############******: initLoader called with id 1111 
12-07 01:38:52.851 9756-9756/me.abhishekraj.showmyshow V/############******: onCreateLoader called with id 1111 
12-07 01:38:52.851 9756-9756/me.abhishekraj.showmyshow V/############******: startPopularMoviesLoaderManager finished 
12-07 01:38:52.851 9756-9756/me.abhishekraj.showmyshow V/############******: startUpcomingMoviesLoaderManager called 
12-07 01:38:52.851 9756-9756/me.abhishekraj.showmyshow V/############******: initLoader called with id 9999 
12-07 01:38:52.851 9756-9756/me.abhishekraj.showmyshow V/############******: startUpcomingMoviesLoaderManager finished 
12-07 01:38:52.851 9756-9756/me.abhishekraj.showmyshow V/############******: onCreateView savedInstance is null 
12-07 01:38:52.855 9756-9756/me.abhishekraj.showmyshow V/############******: onActivityCreated called and saveInstance is null 
12-07 01:38:53.326 9756-9756/me.abhishekraj.showmyshow V/############******: onLoadFinished called with id 9999 
12-07 01:38:54.033 9756-9756/me.abhishekraj.showmyshow V/############******: onLoadFinished called with id 1111 
After a upcoming movie poster is clicked 
12-07 01:30:04.572 2256-2256/me.abhishekraj.showmyshow V/############******: onSaveInstanceState called 
After coming back from DetailActivity 
12-07 01:39:51.672 9756-9756/me.abhishekraj.showmyshow V/############******: onLoaderReset called 
12-07 01:39:51.672 9756-9756/me.abhishekraj.showmyshow V/############******: onLoaderReset called 
12-07 01:39:51.759 9756-9756/me.abhishekraj.showmyshow V/############******: onCreate called 
12-07 01:39:51.759 9756-9756/me.abhishekraj.showmyshow V/############******: onCreate savedInstance is empty 
12-07 01:39:51.759 9756-9756/me.abhishekraj.showmyshow V/############******: startPopularMoviesLoaderManager called 
12-07 01:39:51.759 9756-9756/me.abhishekraj.showmyshow V/############******: initLoader called with id 1111 
12-07 01:39:51.759 9756-9756/me.abhishekraj.showmyshow V/############******: onCreateLoader called with id 1111 
12-07 01:39:51.760 9756-9756/me.abhishekraj.showmyshow V/############******: startPopularMoviesLoaderManager finished 
12-07 01:39:51.760 9756-9756/me.abhishekraj.showmyshow V/############******: startUpcomingMoviesLoaderManager called 
12-07 01:39:51.760 9756-9756/me.abhishekraj.showmyshow V/############******: initLoader called with id 9999 
12-07 01:39:51.760 9756-9756/me.abhishekraj.showmyshow V/############******: startUpcomingMoviesLoaderManager finished 
12-07 01:39:51.761 9756-9756/me.abhishekraj.showmyshow V/############******: onCreateView savedInstance is null 
12-07 01:39:51.765 9756-9756/me.abhishekraj.showmyshow V/############******: onActivityCreated called and saveInstance is null 
12-07 01:39:51.815 9756-9756/me.abhishekraj.showmyshow V/############******: onLoadFinished called with id 1111 
12-07 01:39:51.817 9756-9756/me.abhishekraj.showmyshow V/############******: onLoadFinished called with id 9999 
on rotate 
12-07 01:40:18.441 9756-9756/me.abhishekraj.showmyshow V/############******: onSaveInstanceState called 
12-07 01:40:18.472 9756-9756/me.abhishekraj.showmyshow V/############******: onCreate called 
12-07 01:40:18.472 9756-9756/me.abhishekraj.showmyshow V/############******: onCreate savedInstance is not empty 
12-07 01:40:18.478 9756-9756/me.abhishekraj.showmyshow V/############******: onCreateView savedInstance is Bundle[{upcomingMovies=[me.abhishekraj[email protected], [email protected], [email protected],.......and so on..that means it's not empty 
onRotating back 
12-07 01:40:48.244 9756-9756/me.abhishekraj.showmyshow V/############******: onSaveInstanceState called 
12-07 01:40:48.281 9756-9756/me.abhishekraj.showmyshow V/############******: onCreate called 
12-07 01:40:48.281 9756-9756/me.abhishekraj.showmyshow V/############******: onCreate savedInstance is not empty 
12-07 01:40:48.286 9756-9756/me.abhishekraj.showmyshow V/############******: onCreateView savedInstance is Bundle[{upcomingMovies=[[email protected], [email protected], [email protected], [email protected], [email protected], [email protected],.....and so on...that means it's not empty` 

문제는 그 다음이다? 두 번째 경우 (???)에서 활동이 다시 생성 된 경우에도 다른 활동에서이 조각으로 돌아갈 때 비어있는 saveInstanceState를 얻지 만 화면 회전을 위해서는 null이 아닌 saveInstanceState를 가져 오는 이유는 무엇입니까? 감사합니다.

편집 : 내 코드의 이상이 다음의 기준을 위해 필요한 경우

그것이에서 찾을 수 있습니다 다음 Gist

답변

0

문제는 사용 발사 모드의 경우 주를 위해 아주 쉽게 처리 할 수 ​​있습니다 내 사용 사례에서 완전히 수용 가능한 단일 최상위 활동 훨씬 더 나은 방법이 파괴되기 전에 그래서 활동 상태가 저장 될 수 Back Stack를 사용하여이 될 수

<activity 
     android:name=".MainActivity" 
     android:launchMode="singleTop"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

을하지만 : 여기 내 manifest.xml이 문제를 해결 한 후 모습입니다. 나는 백 스택을 사용하여 해결할 때 대답을 업데이트 할 것이지만 지금은 그 작업을 수행한다.