Java Android GridView、异步任务和屏幕旋转
我在活动中处理屏幕旋转和异步任务时遇到问题。 问题是: 我有一个main活动,它包含一个PostersFragment,负责管理布局。在它里面有一个GridView,用来填充异步任务获取的一些图像。 当我旋转设备时,它会把事情搞砸,我可以在实际的GridView后面看到一个旧的GridView。 这肯定是一个与活动的再现有关的问题,我在谷歌上搜索了很多,找到了setRetainInstancetrue方法,我试图在片段中调用它,但没有任何改变。 以下是主要活动代码: } 我怎样才能防止它复制?如何处理配置更改?在onCreate for Main活动中,替换此行:Java Android GridView、异步任务和屏幕旋转,java,android,android-fragments,gridview,android-asynctask,Java,Android,Android Fragments,Gridview,Android Asynctask,我在活动中处理屏幕旋转和异步任务时遇到问题。 问题是: 我有一个main活动,它包含一个PostersFragment,负责管理布局。在它里面有一个GridView,用来填充异步任务获取的一些图像。 当我旋转设备时,它会把事情搞砸,我可以在实际的GridView后面看到一个旧的GridView。 这肯定是一个与活动的再现有关的问题,我在谷歌上搜索了很多,找到了setRetainInstancetrue方法,我试图在片段中调用它,但没有任何改变。 以下是主要活动代码: } 我怎样才能防止它复制?如
getFragmentManager().beginTransaction().add(R.id.frame_container, new PostersFragment(), POSTERSFRAGMENT_TAG).commit();
到
编辑:对不起,我没有澄清为什么需要这样做。此检查的目的是查看片段是否已经存在。我们什么时候能确认碎片不在那里?当savedInstanceState为空时。
最初,当第一次创建活动时,Bundle为null。当设备发生配置更改时,将销毁并重新创建所有活动/片段,调用setRetainInstancetrue的活动/片段除外。这些碎片没有被销毁。他们只是附属于新的活动…
在配置更改后重新创建活动时,保留片段的实例已经存在,因此savedInstanceState不为null。因此,您需要检查savedInstanceState==null,然后才继续添加片段以避免重复。这就像一个符咒!再问一个问题。。为什么会这样?我有一些想法,但为了好奇和学习,我想要一个解释,以更好地解释事情。对不起,我第一次没有解释。如果你没有得到它的任何部分,不要犹豫回击。除了一件事,一切都清楚。即使我没有调用我删除的setRetainInstance,您的解决方案仍然有效,因为在问题之前,它不起作用。它只是重新创建片段。这是因为savedInstanceState再次为null吗?setRetainInstancetrue是此检查所防止的。默认情况下,Android不保留片段。碎片生命周期在这里解释得很好:是的,我知道生命周期。。。所以它又是空的,对吗?顺便说一下,我添加了保留,现在一切都很完美,非常感谢!
public class PostersFragment extends android.app.Fragment {
public static final int MAX_PAGES = 50;
public int mPagesLoaded = 0;
private ImageAdapter mImages;
public boolean mIsLoading = false;
public TextView loadingText;
private SharedPreferences sharedPrefs;
private SharedPreferences.OnSharedPreferenceChangeListener spChanged;
public PostersFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mImages = new ImageAdapter(getActivity());
View view = inflater.inflate(R.layout.fragment_main,container,false);
loadingText = (TextView) view.findViewById(R.id.loadingTextView);
loadingText.setVisibility(View.GONE);
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
spChanged = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
mImages.clear();
mPagesLoaded=0;
}
};
sharedPrefs.registerOnSharedPreferenceChangeListener(spChanged);
initGrid(view);
startLoading();
return view;
}
private void startLoading()
{
if(mPagesLoaded>=MAX_PAGES)
return;
if(mIsLoading==true)
return;
mIsLoading=true;
if(loadingText!=null)
loadingText.setVisibility(View.VISIBLE);
new FetchPageTask().execute(mPagesLoaded + 1);
}
private void stopLoading()
{
if(mIsLoading==false)
return;
if(mIsLoading==true)
mIsLoading=false;
if(loadingText!=null)
loadingText.setVisibility(View.GONE);
}
private void initGrid(View view)
{
GridView gridView = (GridView) view.findViewById(R.id.gridView);
if(gridView==null)
return;
gridView.setAdapter(mImages);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
ImageAdapter adapter = (ImageAdapter) parent.getAdapter();
Movie movie = adapter.getItem(position);
if (movie == null)
return;
//intent to be launched
Intent intent = new Intent(getActivity(),DetailActivity.class);
intent.putExtra(Movie.EXTRA_MOVIE,movie.toBundle());
getActivity().startActivity(intent);
}
});
gridView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int lastScreen = firstVisibleItem + visibleItemCount;
if(lastScreen == totalItemCount)
startLoading();
}
});
}
private class FetchPageTask extends AsyncTask<Integer,Void,Collection<Movie>> {
public final String LOG_TAG = FetchPageTask.class.getSimpleName();
@Override
protected Collection<Movie> doInBackground(Integer... params) {
if (params.length == 0)
return null;
int page = params[0];
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String responseJsonStr = null;
try {
final String API_BASE_URL = "http://api.themoviedb.org/3/movie/";
final String API_PARAM_PAGE = "page";
final String API_PARAM_KEY = "api_key";
final String API_SORTING = sharedPrefs.getString(getString(R.string.pref_sorting_key),getString(R.string.pref_sorting_default_value));
Uri builtUri = Uri.parse(API_BASE_URL).buildUpon()
.appendPath(API_SORTING)
.appendQueryParameter(API_PARAM_PAGE, String.valueOf(page))
.appendQueryParameter(API_PARAM_KEY, getString(R.string.my_api_key))
.build();
Log.d(LOG_TAG, "Query URI: " + builtUri.toString());
URL url = new URL(builtUri.toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null)
return null;
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null)
buffer.append(line + "\n");
if (buffer.length() == 0)
return null;
responseJsonStr = buffer.toString();
} catch (Exception e) {
Log.e(LOG_TAG, "Error", e);
return null;
} finally {
if (urlConnection != null)
urlConnection.disconnect();
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
Log.e(LOG_TAG, "Error closing input stream", e);
}
}
}
try {
return fetchMoviesFromJson(responseJsonStr);
} catch (JSONException je) {
Log.d(LOG_TAG, "Can't parse JSON " + responseJsonStr, je);
return null;
}
}
private Collection<Movie> fetchMoviesFromJson(String jsonStr) throws JSONException {
final String KEY_MOVIES = "results";
JSONObject json = new JSONObject(jsonStr);
JSONArray movies = json.getJSONArray(KEY_MOVIES);
ArrayList<Movie> result = new ArrayList<Movie>();
for (int i = 0; i < movies.length(); i++) {
result.add(Movie.getMovieFromJson(movies.getJSONObject(i)));
}
return result;
}
@Override
protected void onPostExecute(Collection<Movie> movies)
{
stopLoading();
mPagesLoaded++;
mImages.addAll(movies);
}
}
getFragmentManager().beginTransaction().add(R.id.frame_container, new PostersFragment(), POSTERSFRAGMENT_TAG).commit();
if (savedInstanceState == null) {
getFragmentManager().beginTransaction().add(R.id.frame_container, new PostersFragment(), POSTERSFRAGMENT_TAG).commit();
}