3

I sitting and trying to make some exercises with Android. My point for today is to make simple application which will download data (images from URLs) and show them in ImageView control in the layout. I saw some examples on the web and have done my app. Everything seems to be ok but when I push the button I starts its job but then fails showing error : NULL POINTER 9error reading file). Here is my code:

package com.example.htmlcontent;

import java.io.BufferedInputStream;

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

import android.app.Activity;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;


    public class MainActivity extends Activity {
        private ImageView mImageView;
        private ImageView mImageView2;
        public Button button;
        public static ArrayList<Drawable> drawable;

        public static String[] URLs = {"http://zitterman.com/wp-content/uploads/2013/07/19194927_1371972212.jpg","http://i.imgur.com/CQzlM.jpg"};

        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);


            mImageView = (ImageView) findViewById(R.id.test_image);
            mImageView2 = (ImageView) findViewById(R.id.test_image2);
            button = (Button) findViewById(R.id.download1);

            button.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    new DownloadImage().execute();
                }
            });
        }


        /**
         * Simple functin to set a Drawable to the image View
         * @param drawable
         */
        @SuppressWarnings("deprecation")
        private void setImage()
        {
            if(drawable.get(0) == null)
            {
                System.out.println("DRAWABLE JEST NULL");
            }
            mImageView.setBackgroundDrawable(drawable.get(0));
            mImageView2.setBackgroundDrawable(drawable.get(1));
        }

        public class DownloadImage extends AsyncTask<Void, Void, Void> {



            /**
             * Called after the image has been downloaded
             * -> this calls a function on the main thread again
             */
            protected void onPostExecute(Drawable image)
            {
                setImage();
            }
            protected void onPreExecute()
            {
                Log.i("333333", "Uruchamiam WATEK SCIAGANIA ASYNCTASKIEM PLIKU Z NETA");
            }

            @Override
            protected Void doInBackground(Void... params) {

                downloadImage();
                return null;
            }
            /**
             * Actually download the Image from the _url
             * @param _url
             * @return
             */
            @SuppressWarnings("deprecation")
            private void downloadImage()
            {
                //Prepare to download image

                URL url;        

                InputStream in;
                BufferedInputStream buf;

                //BufferedInputStream buf;
                for(int i = 0; i<URLs.length; i++)
                {
                    try {
                    url = new URL(URLs[i]);
                    in = url.openStream();

                    // Read the inputstream 
                    buf = new BufferedInputStream(in);

                    // Convert the BufferedInputStream to a Bitmap
                    Bitmap bMap = BitmapFactory.decodeStream(buf);
                    if (in != null) {
                        in.close();
                    }
                    if (buf != null) {
                        buf.close();
                    }

                     drawable.add(new BitmapDrawable(bMap));

                } catch (Exception e) {
                    Log.e("Error reading file", e.toString());
                }

                }

            }


        }
    }

and my XML file layout:

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

    <Button
        android:id="@+id/download1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

<TextView
    android:layout_width="102dp"
    android:layout_height="wrap_content"
    android:text="hello" />

    <ImageView
        android:id="@+id/test_image"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="@drawable/ic_launcher" />
    <ImageView
        android:id="@+id/test_image2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/ic_launcher" />

</LinearLayout>

I have made as you see in code ArrayList which is Drawable list. No error in code. Only that NULL POINTERs.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Darek
  • 193
  • 3
  • 14

3 Answers3

4

I think this is because you forgot to initialize the drawable. Change to:

public static ArrayList<Drawable> drawable = new ArrayList<Drawable>();

Next since your AsyncTask is <Void, Void, Void>. Your post execute should be as follows:

    @Override
    protected void onPostExecute(Void aVoid) {
        setImage();
    }

The generic types <A,B,C> correspond to the parameters and return types of differnt methods. You should read more about it here: https://stackoverflow.com/a/6053673/827110

(For completeness sake) you also need the internet permission in your AndroidManifest.xml add (just before <application..):

<uses-permission android:name="android.permission.INTERNET" />
Community
  • 1
  • 1
Amulya Khare
  • 7,718
  • 2
  • 23
  • 38
1

Change you async task as

 public class DownloadImage extends AsyncTask<Void, Void,  ArrayList<Drawable>> {



        /**
         * Called after the image has been downloaded
         * -> this calls a function on the main thread again
         */
        protected void onPostExecute( ArrayList<Drawable> drawable)
        {
            setImage(drawable);
        }
        protected void onPreExecute()
        {
            Log.i("333333", "Uruchamiam WATEK SCIAGANIA ASYNCTASKIEM PLIKU Z NETA");
        }

        @Override
        protected  ArrayList<Drawable> doInBackground(Void... params) {

            downloadImage();
            return drawable;
        }




 private void setImage(ArrayList<Drawable> drawable)
    {
        if(drawable.get(0) == null)
        {
            System.out.println("DRAWABLE JEST NULL");
        }
        mImageView.setBackgroundDrawable(drawable.get(0));
        mImageView2.setBackgroundDrawable(drawable.get(1));
    }
Smogger
  • 553
  • 5
  • 17
  • Ok thank you it works! But could You tell me why it should be like that? I understand that I send array to AsyncTask statically so first parametr is Void. No update so it is Void. Why the third parametr should not be Void? And in doInBackground...why there is return if I have static Array and it is completed from another function (downloadImage)? Why setImage function should has this parameter if Array is static? – Darek Oct 18 '13 at 15:30
0

Ok, I have correct it as you said. Yes i forgot to initialize this arraylist at the beggining but you were faster than me;) So

public class MainActivity extends Activity {
        private ImageView mImageView;
        private ImageView mImageView2;
        public Button button;
        public static ArrayList<Drawable> drawable = new ArrayList<Drawable>();

        public static String[] URLs = {"http://zitterman.com/wp-content/uploads/2013/07/19194927_1371972212.jpg","http://i.imgur.com/CQzlM.jpg"};

        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);


            mImageView = (ImageView) findViewById(R.id.test_image);
            mImageView2 = (ImageView) findViewById(R.id.test_image2);
            button = (Button) findViewById(R.id.download1);

            button.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    new DownloadImage().execute();
                }
            });
        }


        /**
         * Simple functin to set a Drawable to the image View
         * @param drawable
         */
        @SuppressWarnings("deprecation")
        private void setImage( ArrayList<Drawable> drawable)
        {
            if(drawable.get(0) == null)
            {
                System.out.println("DRAWABLE JEST NULL");
            }
            mImageView.setBackgroundDrawable(drawable.get(0));
            mImageView2.setBackgroundDrawable(drawable.get(1));
        }

        public class DownloadImage extends AsyncTask<Void, Void, ArrayList<Drawable>> {

            /**
             * Called after the image has been downloaded
             * -> this calls a function on the main thread again
             */
            protected void onPostExecute( ArrayList<Drawable> drawable)
            {
                setImage(drawable);
            }
            protected void onPreExecute()
            {
                Log.i("333333", "Uruchamiam WATEK SCIAGANIA ASYNCTASKIEM PLIKU Z NETA");
            }

            @Override
            protected ArrayList<Drawable> doInBackground(Void... params) {

                downloadImage();
                return null;
            }
            /**
             * Actually download the Image from the _url
             * @param _url
             * @return
             */
            @SuppressWarnings("deprecation")
            private void downloadImage()
            {
                //Prepare to download image

                URL url;        

                InputStream in;
                BufferedInputStream buf;

                //BufferedInputStream buf;
                for(int i = 0; i<URLs.length; i++)
                {
                    try {
                    url = new URL(URLs[i]);
                    in = url.openStream();

                    // Read the inputstream 
                    buf = new BufferedInputStream(in);

                    // Convert the BufferedInputStream to a Bitmap
                    Bitmap bMap = BitmapFactory.decodeStream(buf);
                    if (in != null) {
                        in.close();
                    }
                    if (buf != null) {
                        buf.close();
                    }

                     drawable.add(new BitmapDrawable(bMap));

                } catch (Exception e) {
                    Log.e("Error reading file", e.toString());
                }

                }

            }


        }
    }

Now it crashes when trying to download images. I do not exacly understand why I should put ArrayList as the third parametr....? Why if I declared static array where i store my images? OnPostExecute it should only call function which will make the rest of work.

Darek
  • 193
  • 3
  • 14
  • You should be editing your original question or posting a new one. Posting an answer is misleading and may get you down votes! – Amulya Khare Oct 18 '13 at 15:18
  • I have updated my answer. Everything should work now. I hope you have added internet permission to your android.manifest. – Amulya Khare Oct 18 '13 at 15:44
  • Here in doInBackground method you are returning null,change it to return drawable , because whatever you return something in doInbackground, it goes to postexecute, and yes you can use it without giving parameters in async task because you array is static, but if you give paramenter as you are giving dont forget to return the result of doinbackground i.e drawable . – Smogger Oct 19 '13 at 03:11