0

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!

+1

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. –

+0

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

Antwort

0

Sie sollten updateMovies(); von onStart() zu onCreateView ändern. Wie Gabe Sechan sagte, liegst du falsch mit dem Lebenszyklus. Versuchen Sie, den Fragment-Lebenszyklus zu erforschen.

+0

Yeh .. Erstanruf OnCreateView() ;. –

+1

Link zum Fragment Lebenszyklus http://developer.android.com/guide/components/fragments.html#Creating –

+0

hi .. Ich habe versucht, Änderungen .. es funktioniert nicht. – Viv

0

Sie müssen nur Methode updateMovies() aufrufen; von onCreateView() nach posterGridView = (GridView) rootView.findViewById (R.id.gridview_movie);

Anruf von start() entfernen;

+0

hi .. Ich habe versucht, Änderungen .. es funktioniert nicht. – Viv