-1

我从Android Hive获得了一个代码来解析来自 url 的 JSON 数据。然后我尝试在Rotten Tomatoes Upcoming Movies Api上实现相同的代码。我已经实现了相同的代码,几乎根据我的需要修改了所有 xml 文件。但问题是当我尝试运行代码时,它显示 NetworkOnMainThread 异常。

这是我的代码。

public class Upcoming extends ListActivity
{
    String url = "http://api.rottentomatoes.com/api/public/v1.0/lists/movies/upcoming.json?apikey=yvvgsv722gy2zkey3ebkda5t";

    final String TAG_MOVIES = "movies";
    final String TAG_ID = "id";
    final String TAG_TITLE = "title";
    final String TAG_YEAR = "year";
    final String TAG_MPAA_RATING = "mpaa_rating";
    final String TAG_RUNTIME = "runtime";
    final String TAG_RELEASE_DATES = "release_dates";
    final String TAG_RATINGS = "ratings";
    final String TAG_CRITIC_RATING = "critics_ratings";
    final String TAG_AUDIENCE_RATING = "audience_ratings";
    final String TAG_SYNOPSIS = "synopsis";
    final String TAG_POSTERS = "posters";

    JSONArray upcomings = null;

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

        ArrayList<HashMap<String, String>> UpcomingList = new ArrayList<HashMap<String, String>>();


     // Creating JSON Parser instance
        JSONParser jParser = new JSONParser();

        // getting JSON string from URL
        JSONObject json = jParser.getJSONFromUrl(url);

        try {
            // Getting Array of Contacts
            upcomings = json.getJSONArray(TAG_MOVIES);

            // looping through All Contacts
            for(int i = 0; i < upcomings.length(); i++){
                JSONObject c = upcomings.getJSONObject(i);

                // Storing each json item in variable
                String id = c.getString(TAG_ID);
                String title = c.getString(TAG_TITLE);
                String year = c.getString(TAG_YEAR);
                String mpaa_rating = c.getString(TAG_MPAA_RATING);
                String runtime = c.getString(TAG_RUNTIME);

                JSONObject release_dates = c.getJSONObject(TAG_RELEASE_DATES);
                JSONObject ratings = c.getJSONObject(TAG_RATINGS);
                String critic_rating = c.getString(TAG_CRITIC_RATING);
                String audience_rating = c.getString(TAG_AUDIENCE_RATING);
                String synopsis = c.getString(TAG_SYNOPSIS);
                JSONObject posters = c.getJSONObject(TAG_POSTERS);


                HashMap<String, String> map = new HashMap<String, String>();

                map.put(TAG_TITLE, title);
                map.put(TAG_YEAR, year);
                map.put(TAG_CRITIC_RATING, critic_rating);
                map.put(TAG_AUDIENCE_RATING, audience_rating);

                UpcomingList.add(map);

            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        ListAdapter adapter = new SimpleAdapter(this, UpcomingList,
                R.layout.activity_upcoming,
                new String[] { TAG_TITLE, TAG_YEAR, TAG_CRITIC_RATING, TAG_AUDIENCE_RATING }, new int[] 
                        {
                        R.id.title, R.id.year, R.id.critic_rating, R.id.audience_rating });

        setListAdapter(adapter);

        // selecting single ListView item
        ListView lv = getListView();

        // Launching new screen on Selecting Single ListItem
        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                // getting values from selected ListItem
                String name = ((TextView) view.findViewById(R.id.title)).getText().toString();
                String cost = ((TextView) view.findViewById(R.id.year)).getText().toString();
                String critic_rating = ((TextView) view.findViewById(R.id.critic_rating)).getText().toString();
                String audience_rating = ((TextView) view.findViewById(R.id.audience_rating)).getText().toString();

                // Starting new intent
                Intent in = new Intent(getApplicationContext(), Upcoming.class);
                in.putExtra(TAG_TITLE, name);
                in.putExtra(TAG_YEAR, cost);
                in.putExtra(TAG_CRITIC_RATING, critic_rating);
                in.putExtra(TAG_AUDIENCE_RATING, audience_rating);
                startActivity(in);
            }
        });
    }
}
4

5 回答 5

2

不要在主线程(UI 线程)中使用网络连接使用 Asyntask 或线程来做。

于 2013-07-02T11:02:14.063 回答
1

使用异步任务

例如 : -

 class YourTask extends AsyncTask<URL, Integer, String> {
 protected String doInBackground(URL... urls) {
     // Fetch Data (Task A)
     return "Result";
 }

 protected void onProgressUpdate(Integer... progress) {
     // Show progress
 }

 protected void onPostExecute(String result) {
     // Show UI after complete (Task B)
 }
}

或者

在 onCreate() 方法中添加以下代码以使用以下代码禁用严格模式

这不是解决方案,但避免了主线程上的网络 IO,所以我推荐AsyncTask

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
            .permitAll().build();
    StrictMode.setThreadPolicy(policy);
}
于 2013-07-02T11:22:09.257 回答
0

请将您的互联网连接过程代码放入ASyncTask或其他线程中。由于 ICS 和 Jelly Bean 不允许您在主线程上进行 Internet 进程。

于 2013-07-02T11:01:22.117 回答
0

您正在主 UI 线程中解析。这就是它抛出错误的原因..您应该为此使用 runOnUiThread 或 AsycTask 。

JSONObject json = jParser.getJSONFromUrl(url);

把上面的行如下:

loadingDialog = ProgressDialog.show(youractivity.this, "", "Loading...", true, false);
new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                    runOnUiThread(new Runnable() {
                        public void run() {
                                                loadingDialog.dismiss();
                                                JSONObject json = jParser.getJSONFromUrl(url);
                                           }
                    });
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }).start();
于 2013-07-02T11:01:40.980 回答
0

不要在 UI / 主线程上执行 http 请求- 您的同步 http 被阻塞,这样做会阻塞屏幕上的实际绘制和布局传递。

执行 http 以响应 UI 事件,就像您尝试在 Android 中做的那样常见,他们发明了一个名为AsyncTask的惊人助手。

创建这个类的匿名实例,内部引用封闭的 Activity 类(即,实际上,在您的 Activity 中定义该类,不要使其成为静态的)。

从上面的文档:

当一个异步任务被执行时,该任务经过...

doInBackground(Params...),在 onPreExecute() 完成执行后立即在后台线程上调用。此步骤用于执行可能需要很长时间的后台计算。...

onPostExecute(Result),在后台计算完成后在 UI 线程上调用。后台计算的结果作为参数传递给该步骤。

[我省略了额外的细节,也是我的重点]。

您的适配器应该引用一个异步任务,该任务将信息从一个执行的代码块(其中包含所有同步 http 请求)从 UI 线程传递到 UI 线程上可用于触摸其视图的代码块(您更新您的列表视图在这里)。

最好的,

汤姆。

于 2013-07-02T11:03:28.310 回答