1

なんだか腑に落ちないみたいです。8-} データベースから JSON データを要求するアクティビティがあり、返される結果には画像 URL が含まれます。私のアプリは Android v2.x で正常に動作しますが、偶然見つけなければならなかったように、Android 4 では奇妙な動作 (画像が読み込まれないなど) があります (これは互換性とは言えませんか?!)。修正が Android 2.x システムの機能を台無しにしないことを願って、それを修正してください!

基本的に、アクティビティは Web 上の多数の例で説明されているとおりに機能します (コードを本質的な部分に切り詰めるために、ほとんどのエラー チェックなどを削除しました)。

 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を返す場合は、結果タイプとして(Stringの代わりに)Voidを使用できます。
于 2012-07-11T10:47:43.770 に答える