2016-02-21 57 views
0

好了,到目前为止,我的MainActivity这个简单的应用程序是这样的:Android应用程序不会从第一正常运行,尝试

public class MainActivity extends AppCompatActivity { 

ListView moviesListView; 
ArrayList <Movie> moviesList; 
MoviesAdapter moviesAdapter; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    moviesListView = (ListView) findViewById(R.id.moviesListView); 
    moviesList = new ArrayList<Movie>(); 

    runProgram(); 
    moviesAdapter = new MoviesAdapter(getApplicationContext(), R.layout.movies_layout, moviesList); 
    moviesListView.setAdapter(moviesAdapter); 
} 

private void runProgram() { 

    String url = "https://api.themoviedb.org/3/" + 
      "discover/movie?primary_release_date.gte=2016-02-01&primary_release_date.lte=2016-02-18" + 
      "&api_key=..............................."; 

    JsonObjectRequest jsObjRequest = new JsonObjectRequest 
      (Request.Method.GET, url, null, new Response.Listener<JSONObject>() { 

       @Override 
       public void onResponse(JSONObject response) { 
        getMovies(response); 
       } 
      }, new Response.ErrorListener() { 

       @Override 
       public void onErrorResponse(VolleyError error) { 
        // TODO Auto-generated method stub 

       } 
      }); 

    // Access the RequestQueue through your singleton class. 
    MySingleton.getInstance(this).addToRequestQueue(jsObjRequest); 
} 


private void getMovies(JSONObject response) { 
    JSONArray jsonArray = null; 
    String imageBaseURL = "http://image.tmdb.org/t/p/w500"; 
    try { 
     jsonArray = response.getJSONArray("results"); 
     for (int i = 0; i < 5; i++){ 
      Movie movie = new Movie(jsonArray.getJSONObject(i).getString("title"), 
        jsonArray.getJSONObject(i).getString("overview"), 
        imageBaseURL + jsonArray.getJSONObject(i).getString("poster_path") 
        + "?&api_key=6b54bd769063ac68b99fac57aa334eae"); 
      moviesList.add(movie); 
     } 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 
} 

}

我想在这里做的就是要求电影来自TMDB,并将它们显示在一个ListView中。但我的问题是,你第一次运行应用程序,它不显示任何东西,你只会看到白屏。 现在,如果您再次运行它,它会在ListView中显示电影。但是,如果您清除应用程序的缓存并尝试再次运行一次,则会再次看到白色屏幕......。我对这里发生的事情感到困惑。 我试着调试过它,它看起来好像是获取数据的速度非常快,所以无论发生什么事情发生之后。

而且,这里是我的适配器的情况下,代码:

public class MoviesAdapter extends ArrayAdapter<Movie> { 

    ArrayList<Movie> moviesList; 
    int adapterResource; 
    Context adapterContext; 
    LayoutInflater layoutInflator; 

    public MoviesAdapter(Context context, int resource, ArrayList<Movie> objects) { 
     super(context, resource, objects); 

     moviesList = objects; 
     adapterResource = resource; 
     adapterContext = context; 
     layoutInflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     final ViewHolder viewHolder; 
     if (convertView == null){ 
      convertView = layoutInflator.inflate(adapterResource, null); 
      viewHolder = new ViewHolder(); 

      viewHolder.movieImage = (ImageView) convertView.findViewById(R.id.movieImage); 
      viewHolder.movieName = (TextView) convertView.findViewById(R.id.movieName); 
      viewHolder.movieOverview = (TextView) convertView.findViewById(R.id.movieOverview); 

      convertView.setTag(viewHolder); 
     } 
     else { 
      viewHolder = (ViewHolder) convertView.getTag(); 
     } 

     new DownloadImageTask(viewHolder.movieImage).execute(moviesList.get(position).getImageURL()); 
     viewHolder.movieName.setText(moviesList.get(position).getName()); 
     viewHolder.movieOverview.setText(moviesList.get(position).getOverview()); 
     return convertView; 
    } 


    public static class ViewHolder{ 
     public ImageView movieImage; 
     public TextView movieName; 
     public TextView movieOverview; 
    } 

    private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { 
     ImageView bmImage; 

     public DownloadImageTask(ImageView bmImage) { 
      this.bmImage = bmImage; 
     } 

     protected Bitmap doInBackground(String... urls) { 
      String urldisplay = urls[0]; 
      Bitmap mIcon11 = null; 
      try { 
       InputStream in = new java.net.URL(urldisplay).openStream(); 
       mIcon11 = BitmapFactory.decodeStream(in); 
      } catch (Exception ex) { 
       Log.e("Error", ex.getMessage()); 
       ex.printStackTrace(); 
      } 
      return mIcon11; 
     } 

     protected void onPostExecute(Bitmap result) { 
      bmImage.setImageBitmap(result); 
     } 

    } 

} 

任何帮助将非常感激。

回答

1

每次调用getView()时,都会启动一个新的DownloadTask。这是完全错误的,因为相同的图像可能已经被下载/在这个过程中

使用通用图像装载机或毕加索的下载:

取而代之的是:

new DownloadImageTask(viewHolder.movieImage).execute(moviesList.get(position).getImageURL()); 

用途:

Picasso.with(context) 
    .load(moviesList.get(position).getImageURL()) 
    .into(viewHolder.movieImage); 

另外,看起来你的getMovies()函数是在主线程上执行的。既然你在这里解析JSON,通过使用AsyncTask

再次将其移动到后台线程,你做​​后,你需要调用notifyDataSetChange()moviesAdapter

+0

代码应该去哪里是什么呢?而不是什么?谢谢,我会尽快让你知道。 –

+0

@ billy_b29查看编辑 –

+0

太棒了!它通过添加毕加索库和moviesAdapter.notifyDataSetChange()来工作。现在我将阅读有关多线程的内容,以便添加它。感谢您的帮助!我一次学会了3件新事物。 –

相关问题