下载图像 - 我的应用程序挂起,显然至少

时间:2014-04-03 13:18:52

标签: android multithreading android-asynctask imageview hang

我写了以下应用程序,从互联网上下载图像,然后在imageview中显示。但这似乎永远挂了。它是否与互联网的速度有关(它是一个小图像,尺寸为340 * 340像素,并且通常在我通常将其保存在计算机上时没有时间),或者代码是否有问题?

package com.example.concurrency;

import java.io.InputStream;
import java.net.URL;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ImageView;

public class UsingAsyncTask extends Activity {
    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.using_asynctask); 
        String spec="http://www.google.com/imgres?imgurl=http%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2F7%2F7a%2FBasketball.png&imgrefurl=http%3A%2F%2Fcommons.wikimedia.org%2Fwiki%2FFile%3ABasketball.png&h=340&w=340&tbnid=EJmjEDyJzrhAuM%3A&zoom=1&docid=C_hn8nOgsGmuwM&hl=en&ei=Q0o2U93LNcaIygH4mICQBQ&tbm=isch&ved=0CHwQhBwwBg&iact=rc&dur=3875&page=1&start=0&ndsp=14";
        URL params = null;
        try {params= new URL(spec);} catch(Exception e) {}
        //Bitmap result;
        new MyTask().execute(params);
        imageView= (ImageView) findViewById(R.id.imageview);
    }

    private class MyTask extends AsyncTask<URL, Void, Bitmap> {

        private Bitmap loadImageFromNetwork(String url){
            try {
            Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(url).getContent());
            return bitmap;
            } catch (Exception e) {
            e.printStackTrace();
            }
            return null;
        }

        /*protected void onPreExecute() {

        }*/

        @Override 
        protected Bitmap doInBackground(URL... params){
            //if(isCancelled()) return;
            String url=params[0].toString();
            final Bitmap bitmap= loadImageFromNetwork(url);
            return bitmap;
        }

        /*protected void onProgressUpdate(Progress progress){
            setProgressPercent(progress[0]);
        }*/

        @Override 
        protected void onPostExecute(Bitmap result){
            imageView.setImageBitmap(result);
        }

    }

}

清单文件: -

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.concurrency"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.INTERNET"></uses-permission>

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.concurrency.UsingAsyncTask"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

布局: -

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >



<ProgressBar
    android:id="@+id/progressbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="4dip"
    android:indeterminate="false"
    android:max="10"/>

<ImageView
    android:id="@+id/imageview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="4dip"
    android:contentDescription="@string/imageview"/>

</LinearLayout>

2 个答案:

答案 0 :(得分:1)

我认为您使用的是Google图片搜索网址,它可能需要更长时间才能阅读。我在下面提到了图像实际链接。请使用此直接链接,以便更快/更好地加载。

因为Google可能需要三次或请求,但这是该文件的直接链接,这就是原因....

http://upload.wikimedia.org/wikipedia/commons/7/7a/Basketball.png

然后使用这种方法从Url中读取图像......

public static class BitmapWorkerTask extends
            AsyncTask<String, Void, Bitmap> {
        private int ht;
        private int wt;

        // Decode image in background.
        public BitmapWorkerTask(int progress, int ht, int wt) {
            this.ht = ht;
            this.wt = wt;
        }

        @Override
        protected Bitmap doInBackground(String... params) {
                URL url;
                try {
                    url = new URL(string);
                    if (getBitmapFromMemCache(position) == null) {
                        HttpURLConnection connection = (HttpURLConnection) url
                                .openConnection();
                        connection.setConnectTimeout(4000);
                        connection.setReadTimeout(10000);
                        int v = connection.getContentLength() > 0 ? connection
                                .getContentLength() : 0;

                            if (v > 0) {
                                InputStream in = new BufferedInputStream(
                                        connection.getInputStream(), 32 * 1024);

                                Bitmap bitmap = decodeSampledBitmapFromResource(
                                        in, ht[i], wt[i]);


                } catch (MalformedURLException e) {
                    // e.printStackTrace();
                } catch (IOException e) {
                    // e.printStackTrace();
                }

            }
            return bitmap ;
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            //Do your bitmap image setting....
                    //image.setImageBitmap(bitmap);
        }

    }

以下方法用于避免内存不足异常....这对于高处理中的图像非常有用...

    public static Bitmap decodeSampledBitmapFromResource(InputStream in,
            int reqWidth, int reqHeight) throws IOException {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        in.mark(in.available());
        BitmapFactory.decodeStream(in, null, options);
        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth,
                reqHeight);
        in.reset();
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeStream(in, null, options);
    }

    public static int calculateInSampleSize(BitmapFactory.Options options,
            int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            // Calculate the largest inSampleSize value that is a power of 2 and
            // keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

答案 1 :(得分:1)

问题在于spec字符串传递给AsyncTask。它指的是HTML页面,而不是图像本身,这就是为什么您无法将InputStream解码为Bitmap的原因。将spec替换为以下值http://upload.wikimedia.org/wikipedia/commons/7/7a/Basketball.png。我测试了这个变化并且它有效。另请注意,如果您在代理服务器后面的模拟器上进行测试,则必须指定代理设置。