我在处理屏幕旋转方面遇到问题,并在我的活动中遇到AsyncTask
。
这就是问题所在:
我有一个MainActivity
,里面有PostersFragment
,负责管理布局。在其中有一个GridView
来填充由AsyncTask
提取的一些图像。
当我旋转设备时,它会消失,我可以看到实际GridView
后面的旧GridView
。
这肯定是一个问题,重新开始活动,我搜索了很多,发现setRetainInstance(true)
方法,我试图在我的片段中调用它,但没有任何改变。
这是MainActivity
代码:
public class MainActivity extends ActionBarActivity {
private final String POSTERSFRAGMENT_TAG ="PFTG";
private DrawerLayout mDrawer;
private ListView mDrawerListView;
private Toolbar toolbar;
private ActionBarDrawerToggle mDrawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getFragmentManager().beginTransaction().add(R.id.frame_container, new PostersFragment(), POSTERSFRAGMENT_TAG).commit();
String[] drawerChoices = getResources().getStringArray(R.array.drawer_choices_array);
mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerListView = (ListView) findViewById(R.id.left_drawer);
mDrawerListView.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, drawerChoices));
mDrawerListView.setOnItemClickListener(new DrawerItemClickListener());
toolbar = (Toolbar) findViewById(R.id.main_activity_toolbar);
if(toolbar!=null){
toolbar.setTitle(getResources().getString(R.string.app_name));
setSupportActionBar(toolbar);
}
mDrawerToggle = new ActionBarDrawerToggle(this,mDrawer,toolbar,R.string.drawer_open,R.string.drawer_close){
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
};
mDrawer.setDrawerListener(mDrawerToggle);
}
private class DrawerItemClickListener implements ListView.OnItemClickListener{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
String x =parent.getItemAtPosition(position).toString();
if(x.equals(getString(R.string.trending_drawer_option))) {
PostersFragment fragment = new PostersFragment();
getFragmentManager().beginTransaction().replace(R.id.frame_container, fragment).commit();
mDrawer.closeDrawer(mDrawerListView);
}
if(x.equals(getString(R.string.bookmarked_drawer_option))){
BookmarksFragment fragment = new BookmarksFragment();
getFragmentManager().beginTransaction().replace(R.id.frame_container,fragment).commit();
mDrawer.closeDrawer(mDrawerListView);
}
if(x.equals(getString(R.string.settings_drawer_option))){
mDrawer.closeDrawer(mDrawerListView);
Intent intent = new Intent(getApplicationContext(),SettingsActivity.class);
startActivity(intent);
}
}
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
boolean drawerOpen = mDrawer.isDrawerOpen(mDrawerListView);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(mDrawerToggle.onOptionsItemSelected(item))
return true;
return super.onOptionsItemSelected(item);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
}
PostersFragment
代码:
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);
}
}
}
如何防止它重复?我应该如何处理配置的变化?
答案 0 :(得分:0)
在您的onCreate
for MainActivity中替换此行:
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();
}
编辑:对不起,我没有说明为什么需要这样做。此检查的目的是查看片段是否已存在。我们什么时候可以确认片段不存在?当savedInstanceState
为null
时
最初,Bundle
在首次创建活动时为null
。当设备进行配置更改时,除了已调用setRetainInstance(true)
的活动/片段外,所有活动/片段都将被销毁并重新创建。这些碎片不会被破坏。他们只是附加到新的活动... savedInstanceState
不是null
。因此,您检查是否savedInstanceState == null
,然后继续添加片段以避免重复。