NetworkOnMainThreadException如何加载图片

时间:2012-07-03 10:23:30

标签: android android-asynctask android-3.0-honeycomb

不知怎的,我似乎没有得到它。 8} 我有一个活动,我从数据库请求JSON数据,返回结果包括图像URL。我的应用程序在Android v2.x上工作正常,但由于我不得不偶然发现,在Android 4上有奇怪的行为 - 包括未加载的图像 - 这不是我所谓的兼容性?!)现在我必须修复此问题,希望修复程序不会再次破坏Android 2.x系统上的功能!

基本上,活动的工作方式与网络上的众多示例中所描述的一致(我删除了大多数错误检查等,以将代码修剪为基本部分):

 new GetProductDetails().execute();
 (..)


 class GetProductDetails extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
            (..)
    }

    protected String doInBackground(String... args) {

        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("pid", pid));
        // getting product details by making HTTP request
        JSONObject json = jsonParser.makeHttpRequest(
                getString(R.string.urlProductDetails), "GET",
                params);
        try {
               JSONArray prodObj = json.getJSONArray(Consts.PRODS);
                pinfo = prodObj.getJSONObject(0);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }


    protected void onPostExecute(String file_url) {
        // updating UI from Background Thread
        runOnUiThread(new Runnable() {
            public void run() {
                // Storing each json item in variable
                try {

                    String s = "";
                    txtvname = (TextView) findViewById(R.id.txtpname);
                    txtshortinfo = (TextView) findViewById(R.id.txtshortinfo);
(… populating activity window with json data …)

            }
        });


        // update image:
        String imgURL;
        try {
            imgURL = pinfo.getString("pic_url");
            if (imgURL.length() > 1) {
                imgURL = getString(R.string.urlPicsFull) + imgURL;
                ImageView imgProd = (ImageView) findViewById(R.id.imgProduct);
                Drawable drawable = LoadImageFromWebOperations(imgURL);
                imgProd.setImageDrawable(drawable);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        pDialog.dismiss();
    }

    private Drawable LoadImageFromWebOperations(String url) {
        try {
            InputStream is = (InputStream) new URL(url).getContent();
            Drawable d = Drawable.createFromStream(is, "src name");
            return d;
        } catch (Exception e) {
            System.out.println("Could not load " + url + ", Exc=" + e);
            return null;
        }
    }

现在,加载图片时会出现android.os.NetworkOnMainThreadException。

1 个答案:

答案 0 :(得分:0)

我认为你的targetSDKVersion太高了。 Here是关于在哪个targetSDKVersion上禁用兼容性行为的一些文档。该列表实际上缺少NetworkOnMainThreadException。它记录在here如下:“这仅针对针对Honeycomb SDK或更高版本的应用程序抛出。针对早期SDK版本的应用程序可以在其主要事件循环线程上进行联网,但强烈建议不要这样做。”

因此,如果将targetSDKVersion降低到Honeycomb以下的值,则可以在主线程上进行联网。将targetSDKVersion设置为某个值就像是说:“我在该级别上测试了我的应用程序。”

  1. onPostExceute始终在主线程上运行。不需要在那里使用runOnUiThread()。
  2. 需要在doInBackground()中调用LoadImageFromWebOperations()以不在主线程上运行。这导致异常。
  3. onPostExecute获取doInBackground返回的参数。因此,如果您不在onPostExcecute中使用该参数并在doInBackground中返回always null,则可以使用Void作为结果类型(而不是String)