我正在开发一个MovieApp,它使用AsyncTask后台线程在MainActivity Fragment中加载电影海报。我正在使用gridview和BaseAdapter来显示图像。以下是代码。
MainActivityFragment.java:
package com.android.example.cinemaapp.app;
import android.app.Fragment;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
public class MainActivityFragment extends Fragment{
MoviePosterAdapter moviePosterAdapter;
GridView posterGridView;
public HashMap<String, JSONObject> movieMap;
public MainActivityFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onStart(){
super.onStart();
updateMovies();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.moviefragment, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_refresh) {
updateMovies();
}
return super.onOptionsItemSelected(item);
}
public void updateMovies(){
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
String sortBy = sharedPreferences.getString(getString(R.string.pref_sort_key), getString(R.string.pref_sort_popular));
new FetchMoviePosterTask().execute(sortBy);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
moviePosterAdapter = new MoviePosterAdapter(getActivity());
posterGridView = (GridView) rootView.findViewById(R.id.gridview_movie);
posterGridView.setAdapter(moviePosterAdapter);
posterGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
// logic to start detail activity
startActivity(intent);
}
});
return rootView;
}
public class FetchMoviePosterTask extends AsyncTask<String, String, Void> implements Serializable {
@Override
protected Void doInBackground(String... params) {
Log.v("FetchMoviePosterTask", "In background method");
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String movieJsonStr;
try {
//logic to create uri builder
URL url = new URL(builtUri.toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
movieJsonStr = null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
movieJsonStr = null;
}
movieJsonStr = buffer.toString();
// Log.v("MainActivityFragment", "Movie json "+movieJsonStr);
try {
String[] posterPaths = getPosterPaths(movieJsonStr);
for(String path : posterPaths){
publishProgress(path);
}
}catch(JSONException je){
Log.e("MoviePosterPath","Error while parsing JSON");
}
} catch (IOException e) {
Log.e("MoviePosterAdapter", "Error ", e);
movieJsonStr = null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("MoviePosterAdapter", "Error closing stream", e);
}
}
}
return null;
}
public String[] getPosterPaths(String movieJsonStr) throws JSONException{
final String POSTER_PATH = //some value
final String POSTER_SIZE = //some value
JSONObject jsonObject = new JSONObject(movieJsonStr);
JSONArray results = jsonObject.getJSONArray("results");
String[] posterStrs = new String[results.length()];
movieMap = new HashMap<String, JSONObject>();
for(int i =0; i < results.length(); i++){
JSONObject movieObj = (JSONObject) results.get(i);
posterStrs[i] = POSTER_PATH + POSTER_SIZE + movieObj.getString("poster_path");
movieMap.put(posterStrs[i], movieObj);
}
return posterStrs;
}
@Override
protected void onProgressUpdate(String... posterValues){
Log.v("FetchMoviePosterTask", "In onProgress method");
moviePosterAdapter.add(posterValues[0]);
super.onProgressUpdate(posterValues);
}
@Override
protected void onPostExecute(Void result) {
Log.v("FetchMoviePosterTask", "In onPostExecute method");
moviePosterAdapter.notifyDataSetChanged();
super.onPostExecute(result);
}
}
}
MoviePosterAdapter.java:
package com.android.example.cinemaapp.app;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class MoviePosterAdapter extends BaseAdapter {
ArrayList<String> movieArray = new ArrayList<String>();
private Context mContext;
public MoviePosterAdapter(Context c) {
mContext = c;
}
void add(String path){
movieArray.add(path);
}
void clear(){
movieArray.clear();
}
void remove(int index){
movieArray.remove(index);
}
@Override
public int getCount() {
return movieArray.size();
}
@Override
public Object getItem(int position) {
return movieArray.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
} else {
imageView = (ImageView) convertView;
}
Picasso.with(mContext).load(movieArray.get(position)).into(imageView);
return imageView;
}
}
问题:首次启动应用程序时,UI不会填充图像视图。在Logcat中,我可以看到控件正在流过doBackground(), onProgressUpdate()
和onPostExecute().
当我点击“刷新&#39;按钮或如果我导航到其他一些活动或应用程序并返回到电影应用程序UI(onResume())它正常工作。显示图像。
非常感谢提前!
答案 0 :(得分:0)
您应该将updateMovies();
从onStart()
更改为onCreateView
。正如Gabe Sechan所说,你对生命周期的看法是错误的。尝试对Fragment生命周期进行一些研究。
答案 1 :(得分:0)
只需要调用方法updateMovies();来自onGreateView()之后的posterGridView =(GridView)rootView.findViewById(R.id.gridview_movie);
从start();
中删除调用