Search code examples
javaandroidparse-platformurlconnectionandroidhttpclient

Migrating from AndroidHttpClient to URLConnection


I'm relatively new to this and I've been using the AndroidHttpClient just fine to help with downloading images to my app via Parse. Now with Sdk 23, I've got to rewrite a few of my classes. My question is fairly simple.

Let's take the following code, which doesn't do anything as an example:

new TwinPrimeSDK(getApplicationContext(), "12345678-1234-1234-1234-123456789012-1234567-123");
    try {
        URLConnection httpConn = TPURLConnection.openConnection("your-URL");
    } catch (IOException e) {
        e.printStackTrace();
    }

What does the "your-URL" refer to? With AndroidHttpClient over Apache I never had to use a specific URL for anything. It just worked.

Update:

public class ImageLoader {

    // Last argument true for LRU ordering
    private Map<String, String> objectIdToUriMap = Collections.synchronizedMap(new LinkedHashMap<String, String>(10, 1.5f, true));

    MemoryCache memoryCache = new MemoryCache();
    FileCache fileCache;
    private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
    ExecutorService executorService;
    // Handler to display images in UI thread
    Handler handler = new Handler();

    public ImageLoader(FileCache fileCache) {
        //fileCache = new FileCache(context);
        this.fileCache = fileCache;
        executorService = Executors.newFixedThreadPool(5);

        // need to re-evaluate where to do this as it is causing problems with not being able to download feed items as they are cleared from cache
        //clearCache();
        // only clear file cache, we're not using mem cache (every time we instantiate with a filecache)
        fileCache.clear();
    }


    public void DisplayImage(String url, ImageView imageView, ProgressBar progress) {
        imageViews.put(imageView, url);
        Bitmap bitmap = memoryCache.get(url);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
        }
        else {
            queuePhoto(url, imageView, progress);
            //imageView.setImageResource(stub_id);
            imageView.setVisibility(View.GONE);

            if(progress != null) {
                progress.setVisibility(View.VISIBLE);
            }
        }
    }

    private void queuePhoto(String url, ImageView imageView, ProgressBar progress) {
        PhotoToLoad p = new PhotoToLoad(url, imageView, progress);
        executorService.submit(new PhotosLoader(p));
    }

    // must be run in a thread
    private Bitmap getBitmap(String url) {
        File f = fileCache.getFile(url);

        Bitmap b = decodeFile(f);
        if (b != null) {
            return b;
        }

        // Download Images from the Internet
        try {
            Bitmap bitmap = null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is = conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
            FeedUtils.CopyStream(is, os);
            os.close();
            conn.disconnect();
            bitmap = decodeFile(f);
            return bitmap;
        } catch (Throwable ex) {
            ex.printStackTrace();
            if (ex instanceof OutOfMemoryError)
                memoryCache.clear();
            return null;
        }
    }

    public Uri getImageURIWithDownload(String url) {
        // try getting file from cache 1st
        File f = fileCache.getFile(url);
        if (f != null) {
            if(f.exists()) {
                return Uri.fromFile(f);
            }
        }

        // get bitmap from http (or cache, in fact)
        getBitmap(url);

        // try getting file again
        f = fileCache.getFile(url);
        return (f != null) ? Uri.fromFile(f) : null;
    }

    // Decodes image and scales it to reduce memory consumption
    // note. wda. doesn't use sample size (no scaling!)
    private Bitmap decodeFile(File f) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            FileInputStream stream1 = new FileInputStream(f);
            BitmapFactory.decodeStream(stream1, null, o);
            stream1.close();

            // Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE = 70;
            int width_tmp = o.outWidth, height_tmp = o.outHeight;
            int scale = 1;
            while (true) {
                if (width_tmp / 2 < REQUIRED_SIZE
                        || height_tmp / 2 < REQUIRED_SIZE)
                    break;
                width_tmp /= 2;
                height_tmp /= 2;
                scale *= 2;
            }

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            //o2.inSampleSize = scale;
            FileInputStream stream2 = new FileInputStream(f);
            Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
            stream2.close();
            return bitmap;
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    // Task for the queue
    private class PhotoToLoad {
        public String url;
        public ImageView imageView;
        public ProgressBar progress;

        public PhotoToLoad(String u, ImageView i, ProgressBar p) {
            url = u;
            imageView = i;
            progress = p;
        }
    }

    class PhotosLoader implements Runnable {
        PhotoToLoad photoToLoad;

        PhotosLoader(PhotoToLoad photoToLoad) {
            this.photoToLoad = photoToLoad;
        }

        @Override
        public void run() {
            try {
                if (imageViewReused(photoToLoad)) { return; }

                Bitmap bmp = getBitmap(photoToLoad.url);
                //memoryCache.put(photoToLoad.url, bmp);

                if (imageViewReused(photoToLoad))  { return; }

                BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
                handler.post(bd);
            } catch (Throwable th) {
                th.printStackTrace();
            }
        }
    }

    boolean imageViewReused(PhotoToLoad photoToLoad) {
        String tag = imageViews.get(photoToLoad.imageView);

        if (tag == null || !tag.equals(photoToLoad.url)) {
            return true;
        }

        return false;
    }

    // Used to display bitmap in the UI thread
    class BitmapDisplayer implements Runnable {
        Bitmap bitmap;
        PhotoToLoad photoToLoad;

        public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
            bitmap = b;
            photoToLoad = p;
        }

        public void run() {
            if (imageViewReused(photoToLoad)) { return; }

            if (bitmap != null) {
                photoToLoad.imageView.setImageBitmap(bitmap);
                photoToLoad.imageView.setVisibility(View.VISIBLE);
                if(photoToLoad.progress != null)
                    photoToLoad.progress.setVisibility(View.GONE);
            }
            else {}
                //photoToLoad.imageView.setImageResource(stub_id);
        }
    }

    public void clearCache() {
        memoryCache.clear();
        fileCache.clear();
    }

}

Solution

  • What does the "your-URL" refer to?

    It refers to the url which you want to access information from.

    With AndroidHttpClient over Apache I never had to use a specific URL for anything. It just worked.

    No you'll provide url in that case too.

    HttpClient httpclient = new DefaultHttpClient();
    HttpResponse response = httpclient.execute(new HttpGet(URL));
    

    If you want to use a http request, it should have a request url, without which it doesn't know where to get data from.