1

不知怎的,我似乎没有得到它。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。

4

1 回答 1

0

我想你的 targetSDKVersion 太高了。以下是有关在哪个 targetSDKVersion 上禁用了哪些兼容性行为的一些文档。该列表中实际上缺少 NetworkOnMainThreadException。此处记录如下:“这仅适用于针对 Honeycomb SDK 或更高版本的应用程序。针对早期 SDK 版本的应用程序允许在其主事件循环线程上进行联网,但非常不鼓励这样做。”

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

  1. onPostExceute 总是在主线程上运行。不需要在那里使用 runOnUiThread() 。
  2. LoadImageFromWebOperations() 需要在 doInBackground() 中调用才能不在主线程上运行。这导致了异常。
  3. onPostExecute 获取 doInBackground 返回的参数。因此,如果您不使用 onPostExcecute 中的参数并在 doInBackground 中始终返回 null,则可以使用 Void 作为结果类型(而不是 String)
于 2012-07-11T10:47:43.770 回答