1

所以我有一个问题,为什么我的函数getIt() 会中断httpGet并给出Exception,在清单中我添加了INTERNET权限!我没有使用 AsyncTask,因为我需要创建一个新类,如果我用它调用 AsyncTask,get它会阻塞我的 UI

类.java

public class loadMovies{
    public String getIt(){
        InputStream ips = null;
        JSONObject json = null;
        String get = "";
        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet("http://mysite/app/movies");
        try {
            HttpResponse response = client.execute(httpGet);
            ips = response.getEntity().getContent();

            BufferedReader buffer = new BufferedReader(new InputStreamReader(ips));
            StringBuilder builder = new StringBuilder();
            String line;

            while((line = buffer.readLine()) != null){
                builder.append(line+"\n");
            }
            json = new JSONObject(builder.toString());
            Log.d(TAG, json.toString());
        }
        catch(Exception e){ e.printStackTrace(); }

        if(json != null){
            JSONArray array = json.optJSONObject("data").optJSONArray("movies");

            for(int i = 0; i < array.length(); i++){
                JSONObject rss = array.optJSONObject(i);
                get += rss.optString("name")+"\n";
            }
        }
        return get;
    }       
}
4

3 回答 3

1

您的应用程序在 Android 3.0 及更高版本上崩溃的原因是 HoneyComb、Ice Cream Sandwich 和 JellyBean 对 UI 线程的滥用更加严格。例如,当运行 HoneyComb 或以上版本的 Android 设备在 UI 线程上检测到网络访问时,会抛出 NetworkOnMainThreadException:

E/AndroidRuntime(673): java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.example/com.example.ExampleActivity}: android.os.NetworkOnMainThreadException

Android 开发人员的网站上有详细记录为什么会发生这种情况的解释:

A NetworkOnMainThreadException is thrown when an application attempts to perform a networking operation on its main thread. This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged. 

ICS 和 HoneyComb 不允许您在 UI 线程上执行的其他一些操作示例如下:

  1. 打开一个 Socket 连接(即 new Socket())。
  2. HTTP 请求(即 HTTPClient 和 HTTPUrlConnection)。
  3. 尝试连接到远程 MySQL 数据库。
  4. 下载文件(即 Downloader.downloadFile())。

如果您尝试在 UI 线程上执行任何这些操作,则必须将它们包装在工作线程中。最简单的方法是使用 AsyncTask,它允许您在用户界面上执行异步工作。AsyncTask 将在工作线程中执行阻塞操作并将结果发布到 UI 线程上,而无需您自己处理线程和/或处理程序。

于 2013-01-05T16:23:24.113 回答
0

如果我用 get 调用 AsyncTask,它会阻止我的 UI

因为正如文档所说的AsyncTask get ()

如有必要,等待计算完成,然后检索其结果。

避免在AsyncTask不调用getUI 线程上的方法的情况下阻止 UI 使用,并doInBackgroundonPostExecute.

将您的 AsyncTask 类创建为:

public class LongloadMovies extends AsyncTask<String, Void, String> {

      @Override
      protected String doInBackground(String... params) {

            loadMovies loadmovobj =new loadMovies();
            String strresult=loadmovobj.getIt();
            return strresult;
      }      

      @Override
      protected void onPostExecute(String result) {     

           // Update your UI here          
      }

}

并从 UI 线程执行 AsyncTask :

new LongloadMovies().execute("");
于 2013-01-05T16:16:37.923 回答
0

您不能在主 ui 线程上进行网络操作。您需要在另一个线程或异步任务中执行此操作。是 tut 谈论这个

于 2013-01-05T16:16:56.363 回答