0

この例外はどのようにすればよいですか?

ターゲット sdkVersion を 13 に変更した後、この問題が発生します。何が悪かったのか?

これは、広告を読み込もうとした後の logcat の出力です。

02-04 12:51:23.910: E/AndroidRuntime(7379): FATAL EXCEPTION: main
02-04 12:51:23.910: E/AndroidRuntime(7379): android.os.NetworkOnMainThreadException
02-04 12:51:23.910: E/AndroidRuntime(7379):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at java.net.InetAddress.getAllByName(InetAddress.java:220)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at libcore.net.http.HttpConnection.<init>(HttpConnection.java:71)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:460)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:432)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:164)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at com.sfa.coverflow.ImageLoader.DisplayAdvert(ImageLoader.java:93)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at com.sfa.coverflow.MainActivity$LoadAdvert.onPostExecute(MainActivity.java:869)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at com.sfa.coverflow.MainActivity$LoadAdvert.onPostExecute(MainActivity.java:1)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at android.os.AsyncTask.finish(AsyncTask.java:602)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at android.os.AsyncTask.access$600(AsyncTask.java:156)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at android.os.Looper.loop(Looper.java:137)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at android.app.ActivityThread.main(ActivityThread.java:4446)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at java.lang.reflect.Method.invokeNative(Native Method)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at java.lang.reflect.Method.invoke(Method.java:511)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
02-04 12:51:23.910: E/AndroidRuntime(7379):     at dalvik.system.NativeStart.main(Native Method)

これは私の DisplayAdvert メソッドです:

int advert_id = R.drawable.loader; 
public void DisplayAdvert(String image_url, int loader, ImageView image) {
    // TODO Auto-generated method stub
    advert_id = loader;
    imageViews.put(image, image_url);
    try {
        URL url = new URL(image_url);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.connect();
        InputStream input = connection.getInputStream();
        Bitmap myBitmap = BitmapFactory.decodeStream(input);
        if(myBitmap!=null)
        image.setImageBitmap(myBitmap);
        else
        {
            queuePhoto(image_url, image);
            image.setImageResource(loader);
        }
    } catch (IOException e) {
        e.printStackTrace();
        }
    }

これは私の LoadAdvert メソッドです:

/**
     * Background Async Task to Load all product by making HTTP Request
     * */
    class LoadAdvert extends AsyncTask<String, String, String> {

        /**
         * getting All products from url
         * */
        protected String doInBackground(String... args) {
            // Building Parameters
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            // getting JSON string from URL
            JSONObject json = jParser.makeHttpRequest(url_advertisement, "GET", params);

            // Check your log cat for JSON reponse
            Log.d("Advert: ", json.toString());

            try {
                // Checking for SUCCESS TAG
                int success = json.getInt(TAG_SUCCESS);

                if (success == 1) {
                    // ADVERT FOUND
                    // RETRIEVE ADVENT URL
                    advert = json.getJSONArray(TAG_PHOTOS);

                    for (int i = 0; i < advert.length(); i++) {
                        JSONObject c = advert.getJSONObject(i);

                        // STORE EACH JSON ITEM IN VARIABLE
                        banner_url = c.getString(TAG_BANNER_IMAGE);
                        banner_url = banner_url.toString();
                        Log.d("banner URL", banner_url);

                        advert_url = c.getString(TAG_ADVERT_URL);
                        advert_url = advert_url.toString();
                        Log.d("advert URL", advert_url);
                    }       
                } 
                else {

                }

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

            return null;
        }

        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) {

                    // Loader image - will be shown before loading image
                    int loader = R.drawable.loader;

                    // Imageview to show
                    ImageView image = (ImageView) findViewById(R.id.img_advert);

                    // Image url
                    String imageUrl = banner_url;

                    // ImageLoader class instance
                    ImageLoader imgLoader = new ImageLoader(getApplicationContext());

                    // whenever you want to load an image from url
                    // call DisplayImage function
                    // url - image url to load
                    // loader - loader image, will be displayed before getting image
                    // image - ImageView 
                    imgLoader.DisplayAdvert(imageUrl, loader, image);           

        }
    }
}
4

5 に答える 5

2

スタック トレースのこの部分が「キラー」です。

at libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:164)
at com.sfa.coverflow.ImageLoader.DisplayAdvert(ImageLoader.java:93)
at com.sfa.coverflow.MainActivity$LoadAdvert.onPostExecute(MainActivity.java:869)

AsyncTask が完了したときにonPostExecuteGUI スレッドで実行されるyour which は、すぐに を呼び出します。新しい API バージョンの GUI スレッドではネットワーク アクセスが許可されていないため、例外がスローされます。DisplayAdvertHttpsURLConnectionImpl.connect

内部のネットワーク アクセスDisplayAdvertは、ネットワーク I/O を実行するため、非 GUI スレッドで行う必要があります。

これを行う最も簡単な方法は、メソッドで新しい AsyncTask を作成しDisplayAdvert、 でネットワーク アクセスをdoInBackground()行い、 で取得したデータで GUI を更新することonPostExecute()です。

于 2013-02-04T05:07:00.760 に答える
0

メインスレッドでネットワーク操作を実行することは想定されていません。

あなたが投稿したコードでは、 でネットワーク操作を実行しており、でdisplay()それを呼び出しています。onPost()AsycTask

AsyncTask別のスレッドで実行されるだけで、doInBackground()メソッドonPost()はメインスレッド自体で実行されます。

その他ご不明な点はお気軽にご質問ください。

于 2013-02-04T05:11:00.210 に答える
0

Honeycomb を対象とするアプリはこの例外を受け取ります。ネットワーク操作はメイン UI スレッドで許可されるべきではありません。

すべてのネットワーク操作を別のスレッド (マルチスレッド) で行うか、AsyncTask を使用する必要があります。

更新しました:

 public void DisplayAdvert(final String image_url, final int loader, final ImageView image) 
    {
        advert_id = loader;
        imageViews.put(image, image_url);
        try 
        {
            new Thread(new Runnable()
            {
                Bitmap myBitmap;
                public void run() 
                {
                    try 
                    {
                        URL url = new URL(image_url);
                        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                        connection.setDoInput(true);
                        connection.connect();
                        InputStream input = connection.getInputStream();
                        myBitmap = BitmapFactory.decodeStream(input);
                    }
                    catch(Exception e)
                    {
                        e.printStackTrace();
                    }
                    runOnUiThread(new Runnable()
                    {
                        public void run() 
                        {
                            if(myBitmap!=null)
                                image.setImageBitmap(myBitmap);
                            else
                            {
                                queuePhoto(image_url, image);
                                image.setImageResource(loader);
                            }
                        }
                    });
                }
            }).start();
       }
       catch (Exception e) 
       {
            e.printStackTrace();
       }
    }
于 2013-02-04T05:13:53.957 に答える
0

単にコードをテストしたい場合は、これに次のコードを追加できますonCreate()

if (android.os.Build.VERSION.SDK_INT > 9) { 
                StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); 
        }

UI スレッドでのネットワーク操作はアプリの使用時に悪いエクスペリエンスをもたらすため、これを永続的にしたくはありませんが、テスト時には役立つ可能性があります。

于 2013-02-04T05:07:29.523 に答える
0

API レベル 11 以降ではメイン スレッドでネットワーク操作を実行できないため、DisplayAdvert メソッドを doInBackground に配置します。

このリソースを参照してください

于 2013-02-04T05:07:31.387 に答える