从第一次尝试开始,Android应用程序无法正常运行

时间:2016-02-21 05:45:19

标签: android android-volley

好的,到目前为止,我对这个简单应用的MainActivity看起来像这样:

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 个答案:

答案 0 :(得分:1)

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

使用Universal Image loader或Picasso:

而不是:

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

使用:

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

此外,似乎您的getMovies()函数在主线程上执行。由于您在此处解析JSON,因此使用AsyncTask

将其移至后台线程

第三,执行getMovies(response);后,您需要致电notifyDataSetChange()

上的moviesAdapter