Ich entwickle eine MovieApp, die Filmplakate in MainActivity Fragment mithilfe von AsyncTask-Hintergrundthread lädt. Ich verwende Gridview und BaseAdapter, um Bilder anzuzeigen. Folgendes ist der Code.MainActvity wird nicht aktualisiert, wenn App erstmals gestartet wird
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;
}
}
Problem: Wenn die Anwendung zum ersten Mal gestartet wird, wird UI nicht mit imageviews bevölkert zu werden. In Logcat konnte ich sehen, Kontrolle fließt durch doBackground(), onProgressUpdate()
und onPostExecute().
Wenn ich Schaltfläche ‚Aktualisieren‘ klicken oder wenn ich auf eine andere Tätigkeit oder App navigieren und zurück zum Film app UI (onResume()) es funktioniert völlig in Ordnung. Bilder werden angezeigt.
Vielen Dank im Voraus!
Sie irren sich über den Lebenszyklus- zu einer anderen App gehen und zurückkommen nicht nur onResume aufrufen, ruft on onStart dann onResume. Die App wird gestoppt (onStop wird aufgerufen), wenn sie vollständig vom Bildschirm verschwindet. onStart wird immer dann aufgerufen, wenn die App aus einem gestoppten Zustand reaktiviert wird. –
Einverstanden .. aber warum es nicht aufgerufen wird, wenn die App zum ersten Mal gestartet wird. Ich habe auch versucht, updateMovies() von onCreateView() aufrufen, es funktioniert immer noch nicht. – Viv