0

我正在尝试制作一个访问 RottenTomatoes.com 并加载即将上映的电影的 API 数据的 Android 应用程序。

我可以成功获取 API 数据,但是当我尝试解析数据时遇到了麻烦。

这是不起作用的代码块:

    public class MovieJSONParser {
    static public class MovieParser{    
        static ArrayList<Movie> parseMovie(String jsonString) throws JSONException {

            ArrayList<Movie> movies = new ArrayList<Movie>();
            JSONObject moviesJSON = new JSONObject(jsonString);
            JSONArray moviesArray = moviesJSON.getJSONArray("movies");
            Log.d("app", "in MovieJSONParser");
            for (int i = 0; i < moviesArray.length(); i++) {
                JSONObject o = moviesArray.getJSONObject(i);
                Log.d("app", o.toString());
                Log.d("app", "Created a JSON object to put in Movies");

                                // THIS LINE ISN'T WORKING
                Movie movie = new Movie(o);     

                Log.d("app", "after Movie declaration");
                movies.add(movie);
            }
            Log.d("app", "end of MovieJSONParser");
            return movies;
        } 
    }
}

我知道我标记为不工作的代码行不起作用,因为日志注释在声明之前都正确显示:

Movie movie = new Movie(o);

这行代码很简单……一个简单的类对象声明……我不知道为什么它会导致程序崩溃……没有实际错误。程序运行。

这是我的Movie.class

    public class Movie extends Activity {
    String url_posterThumbnail, title, year, mpaa_rating;
    int critics_score;

    public Movie(JSONObject o)  throws JSONException {
        Log.d("app", "in Movie");
        this.title = o.getString("title");
        this.year = o.getString("year");
        this.mpaa_rating = o.getString("mpaa_rating");
        this.critics_score = o.getInt("critics_score");
        this.url_posterThumbnail = o.getString("thumbnail");
    }

    public String returnUrl_posterThumbnail() {
        return url_posterThumbnail;
    }

    public void setUrl_posterThumbnail(String url_posterThumbnail) {
        this.url_posterThumbnail = url_posterThumbnail;
    }

    public String returnTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String returnYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

    public String returnMpaa_rating() {
        return mpaa_rating;
    }

    public void setMpaa_rating(String mpaa_rating) {
        this.mpaa_rating = mpaa_rating;
    }

    public int returnCritics_score() {
        return critics_score;
    }

    public void setCritics_score(int critics_score) {
        this.critics_score = critics_score;
    }

    @Override
    public String toString() {
        return "Movie [url_posterThumbnail=" + url_posterThumbnail + ", title="
                + title + ", year=" + year + ", mpaa_rating=" + mpaa_rating
                + ", critics_score=" + critics_score + "]";
    }

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.movies, menu);
        return true;
    }

}

MainActivity.class如果您需要,这是我的:

    public class MainActivity extends Activity {
    String APIKEY = "vs6hcrs57h4wy74u3zgxhmrm";
    String url_MY_FAVORITE_MOVIES = "";
    String url_BOX_OFFICE_MOVIES = "http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json?limit=3&country=us&apikey=p53b5bybwxpg7nfykwzezkzr";
    String url_IN_THEATRES_MOVIES = "http://api.rottentomatoes.com/api/public/v1.0/lists/movies/in_theaters.json?page_limit=3&page=1&country=us&apikey=p53b5bybwxpg7nfykwzezkzr";
    String url_OPENING_MOVIES = "http://api.rottentomatoes.com/api/public/v1.0/lists/movies/opening.json?limit=3&country=us&apikey=p53b5bybwxpg7nfykwzezkzr";
    String url_UPCOMING_MOVIES = "http://api.rottentomatoes.com/api/public/v1.0/lists/movies/upcoming.json?page_limit=3&page=1&country=us&apikey=p53b5bybwxpg7nfykwzezkzr";
    ListView listview;
    ArrayList<Movie> movies = new ArrayList<Movie>();

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

        Log.d("app", "Hi!  In onCreate");
        listview = (ListView) findViewById(R.id.listView1);
        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1);
        listview.setAdapter(arrayAdapter);
        arrayAdapter.add("My Favorite Movies");
        arrayAdapter.add("Box Office Movies");
        arrayAdapter.add("In Theatres Movies");
        arrayAdapter.add("Opening Movies");
        arrayAdapter.add("Upcoming Movies");

        listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int listViewPosition,
                    long arg3) {
                Intent i = new Intent(getBaseContext(), MoviesDetails.class);

                switch (listViewPosition) {
                    case 0:
                        try {
                            movies = new GetMoviesASYNCTASK(MainActivity.this).execute(url_MY_FAVORITE_MOVIES).get();
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        } catch (ExecutionException e1) {
                            e1.printStackTrace();
                        }
                        Log.d("app", "right before starting MoviesDetails activity");
                        i.putExtra("movies", movies);
                        startActivity(i);
                        break;

                    case 1:
                        try {
                            movies = new GetMoviesASYNCTASK(MainActivity.this).execute(url_BOX_OFFICE_MOVIES).get();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } catch (ExecutionException e) {
                            e.printStackTrace();
                        }
                        Log.d("app", "right before starting MoviesDetails activity");
                        i.putExtra("movies", movies);
                        startActivity(i);
                        break;

                    case 2:
                        try {
                            movies = new GetMoviesASYNCTASK(MainActivity.this).execute(url_IN_THEATRES_MOVIES).get();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } catch (ExecutionException e) {
                            e.printStackTrace();
                        }
                        Log.d("app", "right before starting MoviesDetails activity");
                        i.putExtra("movies", movies);
                        startActivity(i);
                        break;

                    case 3:
                        try {
                            movies = new GetMoviesASYNCTASK(MainActivity.this).execute(url_OPENING_MOVIES).get();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } catch (ExecutionException e) {
                            e.printStackTrace();
                        }
                        Log.d("app", "right before starting MoviesDetails activity");
                        i.putExtra("movies", movies);
                        startActivity(i);
                        break;

                    case 4:
                        try {
                            movies = new GetMoviesASYNCTASK(MainActivity.this).execute(url_UPCOMING_MOVIES).get();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } catch (ExecutionException e) {
                            e.printStackTrace();
                        }
                        Log.d("app", "right before starting MoviesDetails activity");
                        i.putExtra("movies", movies);
                        startActivity(i);
                        break;  

                    default: 
                        break;
                }
                Log.d("app", "end of file?");
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

最后,GetMoviesASYNCTASK.class如果您需要,这是我的:

    public class GetMoviesASYNCTASK extends AsyncTask<String, Void, ArrayList<Movie>> {
    String url_string;
    ProgressDialog pd;
    MainActivity main;

    public GetMoviesASYNCTASK(MainActivity main){
        this.main = main;
    }

    @Override
    protected ArrayList<Movie> doInBackground(String... params) {
        url_string = params[0];
//      pd = new ProgressDialog(main);
//      pd.setCancelable(false);
//      pd.setMessage("Loading Movies...!");
//      pd.show();
        Log.d("app", "begin asynctask");

        try {
            URL url = new URL(url_string);//Parse the string as an url  
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            //create a http connection using that url
            con.setRequestMethod("GET");//Use the get method
            con.connect();  //Connect to http
            int statusCode = con.getResponseCode();//Get the server's response
            if (statusCode == HttpURLConnection.HTTP_OK) {  //If server returns 200
                BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
                StringBuilder sb = new StringBuilder();
                String line = reader.readLine();
                while (line != null) {
                    sb.append(line);
                    line = reader.readLine();
                }
                Log.d("app", "String value of API stored");
                ArrayList<Movie> movies = MovieJSONParser.MovieParser.parseMovie(sb.toString());
                Log.d("app", "movies in ASYNCTASK initialized :)");
                return movies;
            }
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        Log.d("app", "asynctask didn't work");
        return null;
    }

    // Override
    protected void onPostExecute(ArrayList<Movie> result) {
        //ArrayList<String> movieTitles = new ArrayList<String>();
        super.onPostExecute(result);
        Log.d("app", "exiting asynctask");
        //pd.dismiss();
    }


}

我错过了一些明显的东西吗?

任何帮助将不胜感激!

4

1 回答 1

0

critics_score 在 rating 对象中,但在这里您尝试直接访问该键。所以它抛出异常。

最好使用带有一些默认值的 optString() 而不是 getString(),因为即使键不存在,也不会以异常结束..


这是工作代码:

JSONObject object = new JSONObject(result);
JSONArray records = object.getJSONArray("movies");

Log.d(LOG_TAG, "records" + records);

int len = records.length();

String albumart[] = new String[len];

for (int i = 0; i < len; i++) {

    JSONObject record = (JSONObject) records.getJSONObject(i);

    String extid = record.getString("id");

    String accountName = record.optString("title", "No title");

    JSONObject posters = record.getJSONObject("posters");

    String albuart = posters.optString("detailed", null);

    String critics = record.optString("critics_consensus", "No Critics");

    String year = record.getString("year");

    String rating = record.optString("mpaa_rating", "No rating");

    JSONObject ratings = record.getJSONObject("ratings");
    String rating = ratings.optString("critics_score", "");

    if(rating.length() <= 0 ) {
        rating = "0";
    }

    String audience_rating = ratings.optString("audience_rating", "");

    if(audience_rating.length() <= 0 ) {
        audience_rating = "0";
    }

    String duration = record.optString("runtime", "");

    if(duration.length() <= 0 ) {
        duration = "0"
    }
}
于 2013-06-20T04:12:36.893 回答