Nullpointerexception on android in project to download Pdfs

Asked

Viewed 103 times

-5

I made an application that at a certain low time Pdfs, however I can only download a PDF. I wanted to download several PDF, see the project. The part that’s making the mistake is in the for, where I try to call 3 times the part that reads the PDF. If I play only 1 string without the for works. See:

Class of Download

public class AndroidFileDownloader extends Activity  {
    // Used to communicate state changes in the DownloaderThread
    public static final int MESSAGE_DOWNLOAD_STARTED = 1000;
    public static final int MESSAGE_DOWNLOAD_COMPLETE = 1001;
    public static final int MESSAGE_UPDATE_PROGRESS_BAR = 1002;
    public static final int MESSAGE_DOWNLOAD_CANCELED = 1003;
    public static final int MESSAGE_CONNECTING_STARTED = 1004;
    public static final int MESSAGE_ENCOUNTERED_ERROR = 1005;

    // instance variables
    private AndroidFileDownloader thisActivity;
    private Thread downloaderThread;
    private ProgressDialog progressDialog;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        thisActivity = this;
        downloaderThread = null;
        progressDialog = null;


        //Cria o arquivo

        File wallpaperDirectory = new File("/sdcard/Wallpaper/");

        wallpaperDirectory.mkdirs();

        File outputFile = new File(wallpaperDirectory, "/Wallpaper/");

        try {
            FileOutputStream fos = new FileOutputStream(outputFile);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        String links[] = null;

        links[0] = "http://lwn.net/images/pdf/20040806_novell_mtd.pdf";
        links[1] = "http://lwn.net/images/pdf/IBM-155.pdf";
        links[2] = "http://lwn.net/images/pdf/IBM-148.pdf";

        for(int i =0; i <=links.length; i++){

        downloaderThread = new DownloaderThread(thisActivity, links[i]);

        downloaderThread.start();
        }

    }

    /**
     * This is the Handler for this activity. It will receive messages from the
     * DownloaderThread and make the necessary updates to the UI.
     */
    public Handler activityHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
            /*
             * Handling MESSAGE_UPDATE_PROGRESS_BAR: 1. Get the current
             * progress, as indicated in the arg1 field of the Message. 2.
             * Update the progress bar.
             */
            case MESSAGE_UPDATE_PROGRESS_BAR:
                if (progressDialog != null) {
                    int currentProgress = msg.arg1;
                    progressDialog.setProgress(currentProgress);
                }
                break;

            /*
             * Handling MESSAGE_CONNECTING_STARTED: 1. Get the URL of the file
             * being downloaded. This is stored in the obj field of the Message.
             * 2. Create an indeterminate progress bar. 3. Set the message that
             * should be sent if user cancels. 4. Show the progress bar.
             */
            case MESSAGE_CONNECTING_STARTED:
                if (msg.obj != null && msg.obj instanceof String) {
                    String url = (String) msg.obj;
                    // truncate the url
                    if (url.length() > 16) {
                        String tUrl = url.substring(0, 15);
                        tUrl += "...";
                        url = tUrl;
                    }
                    String pdTitle = thisActivity
                            .getString(R.string.progress_dialog_title_connecting);
                    String pdMsg = thisActivity
                            .getString(R.string.progress_dialog_message_prefix_connecting);
                    pdMsg += " " + url;

                    dismissCurrentProgressDialog();
                    progressDialog = new ProgressDialog(thisActivity);
                    progressDialog.setTitle(pdTitle);
                    progressDialog.setMessage(pdMsg);
                    progressDialog
                            .setProgressStyle(ProgressDialog.STYLE_SPINNER);
                    progressDialog.setIndeterminate(true);
                    // set the message to be sent when this dialog is canceled
                    Message newMsg = Message.obtain(this,
                            MESSAGE_DOWNLOAD_CANCELED);
                    progressDialog.setCancelMessage(newMsg);
                    progressDialog.show();
                }
                break;

            /*
             * Crie uma barra de progresso com
             * Especificado valor máximo e atual valor 0; atribuí-la a
             * ProgressDialog . O campo arg1 conterá o valor max . 2. Defina
             * O título e um texto para a barra de progresso . O campo do obj
             * Mensagem conterá uma String que representa o nome do
             * Arquivo a ser baixado . 3. Defina a mensagem que deve ser enviada se
             * Diálogo é cancelada. 4. Verifique a barra de progresso visível.
             */
            case MESSAGE_DOWNLOAD_STARTED:
                // obj will contain a String representing the file name
                if (msg.obj != null && msg.obj instanceof String) {
                    int maxValue = msg.arg1;
                    String fileName = (String) msg.obj;
                    String pdTitle = thisActivity
                            .getString(R.string.progress_dialog_title_downloading);
                    String pdMsg = thisActivity
                            .getString(R.string.progress_dialog_message_prefix_downloading);
                    pdMsg += " " + fileName;

                    dismissCurrentProgressDialog();
                    progressDialog = new ProgressDialog(thisActivity);
                    progressDialog.setTitle(pdTitle);
                    progressDialog.setMessage(pdMsg);
                    progressDialog
                            .setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                    progressDialog.setProgress(0);
                    progressDialog.setMax(maxValue);
                    // set the message to be sent when this dialog is canceled
                    Message newMsg = Message.obtain(this,
                            MESSAGE_DOWNLOAD_CANCELED);
                    progressDialog.setCancelMessage(newMsg);
                    progressDialog.setCancelable(true);
                    progressDialog.show();
                }
                break;

            /*
             * Handling MESSAGE_DOWNLOAD_COMPLETE: 1. Remove the progress bar
             * from the screen. 2. Display Toast that says download is complete.
             */
            case MESSAGE_DOWNLOAD_COMPLETE:
                dismissCurrentProgressDialog();
                displayMessage(getString(R.string.user_message_download_complete));
                break;

            /*
             * Handling MESSAGE_DOWNLOAD_CANCELLED: 1. Interrupt the downloader
             * thread. 2. Remove the progress bar from the screen. 3. Display
             * Toast that says download is complete.
             */
            case MESSAGE_DOWNLOAD_CANCELED:
                if (downloaderThread != null) {
                    downloaderThread.interrupt();
                }
                dismissCurrentProgressDialog();
                displayMessage(getString(R.string.user_message_download_canceled));
                break;

            /*
             * Handling MESSAGE_ENCOUNTERED_ERROR: 1. Check the obj field of the
             * message for the actual error message that will be displayed to
             * the user. 2. Remove any progress bars from the screen. 3. Display
             * a Toast with the error message.
             */
            case MESSAGE_ENCOUNTERED_ERROR:
                // obj will contain a string representing the error message
                if (msg.obj != null && msg.obj instanceof String) {
                    String errorMessage = (String) msg.obj;
                    dismissCurrentProgressDialog();
                    displayMessage(errorMessage);
                }
                break;

            default:
                // nothing to do here
                break;
            }
        }
    };

    /**
     * If there is a progress dialog, dismiss it and set progressDialog to null.
     */
    public void dismissCurrentProgressDialog() {
        if (progressDialog != null) {
            progressDialog.hide();
            progressDialog.dismiss();
            progressDialog = null;
        }
    }


    /**
     * Displays a message to the user, in the form of a Toast.
     * 
     * @param message
     *            Message to be displayed.
     */
    public void displayMessage(String message) {
        if (message != null) {
            Toast.makeText(thisActivity, message, Toast.LENGTH_SHORT).show();
        }
    }

    public void openFolder() {

              Intent intent = new Intent();
              intent.setAction(Intent.ACTION_GET_CONTENT);
              intent.setType("Wallpaper/*");
              startActivity(intent);

    }

}

Class of Thread

public class DownloaderThread extends Thread {
    // constants
    private static final int DOWNLOAD_BUFFER_SIZE = 4096;

    // instance variables
    private AndroidFileDownloader parentActivity;
    private String downloadUrl;

    /**
     * Instantiates a new DownloaderThread object.
     * 
     * @param parentActivity
     *            Reference to AndroidFileDownloader activity.
     * @param inUrl
     *            String representing the URL of the file to be downloaded.
     */
    public DownloaderThread(AndroidFileDownloader inParentActivity, String inUrl) {
        downloadUrl = "";
        if (inUrl != null) {
            downloadUrl = inUrl;
        }
        parentActivity = inParentActivity;
    }

    /**
     * Connects to the URL of the file, begins the download, and notifies the
     * AndroidFileDownloader activity of changes in state. Writes the file to
     * the root of the SD card.
     */
    @Override
    public void run() {
        URL url;
        URLConnection conn;
        int fileSize, lastSlash;
        String fileName;
        BufferedInputStream inStream;
        BufferedOutputStream outStream;
        File outFile;
        FileOutputStream fileStream;
        Message msg;

        // we're going to connect now
        msg = Message.obtain(parentActivity.activityHandler,
                AndroidFileDownloader.MESSAGE_CONNECTING_STARTED, 0, 0,
                downloadUrl);
        parentActivity.activityHandler.sendMessage(msg);

        try {
            url = new URL(downloadUrl);
            conn = url.openConnection();
            conn.setUseCaches(false);
            fileSize = conn.getContentLength();

            // get the filename
            lastSlash = url.toString().lastIndexOf('/');
            fileName = "file.bin";
            if (lastSlash >= 0) {
                fileName = url.toString().substring(lastSlash + 1);
            }
            if (fileName.equals("")) {
                fileName = "file.bin";
            }

            // notify download start
            int fileSizeInKB = fileSize / 1024;
            msg = Message.obtain(parentActivity.activityHandler,
                    AndroidFileDownloader.MESSAGE_DOWNLOAD_STARTED,
                    fileSizeInKB, 0, fileName);
            parentActivity.activityHandler.sendMessage(msg);

            // start download
            inStream = new BufferedInputStream(conn.getInputStream());
            outFile = new File(Environment.getExternalStorageDirectory() + "/Wallpaper/"
                    + fileName);
            fileStream = new FileOutputStream(outFile);
            outStream = new BufferedOutputStream(fileStream,
                    DOWNLOAD_BUFFER_SIZE);
            byte[] data = new byte[DOWNLOAD_BUFFER_SIZE];
            int bytesRead = 0, totalRead = 0;
            while (!isInterrupted()
                    && (bytesRead = inStream.read(data, 0, data.length)) >= 0) {
                outStream.write(data, 0, bytesRead);

                // update progress bar
                totalRead += bytesRead;
                int totalReadInKB = totalRead / 1024;
                msg = Message.obtain(parentActivity.activityHandler,
                        AndroidFileDownloader.MESSAGE_UPDATE_PROGRESS_BAR,
                        totalReadInKB, 0);
                parentActivity.activityHandler.sendMessage(msg);
            }

            outStream.close();
            fileStream.close();
            inStream.close();

            if (isInterrupted()) {
                // the download was canceled, so let's delete the partially
                // downloaded file
                outFile.delete();
            } else {
                // notify completion
                msg = Message.obtain(parentActivity.activityHandler,
                        AndroidFileDownloader.MESSAGE_DOWNLOAD_COMPLETE);
                parentActivity.activityHandler.sendMessage(msg);
            }
        } catch (MalformedURLException e) {
            String errMsg = parentActivity
                    .getString(R.string.error_message_bad_url);
            msg = Message.obtain(parentActivity.activityHandler,
                    AndroidFileDownloader.MESSAGE_ENCOUNTERED_ERROR, 0, 0,
                    errMsg);
            parentActivity.activityHandler.sendMessage(msg);
        } catch (FileNotFoundException e) {
            String errMsg = parentActivity
                    .getString(R.string.error_message_file_not_found);
            msg = Message.obtain(parentActivity.activityHandler,
                    AndroidFileDownloader.MESSAGE_ENCOUNTERED_ERROR, 0, 0,
                    errMsg);
            parentActivity.activityHandler.sendMessage(msg);
        } catch (Exception e) {
            String errMsg = parentActivity
                    .getString(R.string.error_message_general);
            msg = Message.obtain(parentActivity.activityHandler,
                    AndroidFileDownloader.MESSAGE_ENCOUNTERED_ERROR, 0, 0,
                    errMsg);
            parentActivity.activityHandler.sendMessage(msg);
        }
    }

}

Analyze the code and see how I can download several PDF.

1 answer

3


  1. If you had a NullPointerException, you could post the stacktrace, right?

  2. In the method run() of your class DownloaderThread, you are not closing the outStream, the inStream and the fileStream within a block finally. That’ll probably get you in trouble.

  3. I may be wrong, but I think updating the state of the progress bar constantly in your while that downloads will likely cause some kind of performance issue that will slow down the download speed.

  4. The field thisActivity it seems to me to be totally unnecessary. Use AndroidFileDownloader.this.

  5. This code definitely is wrong:

    for(int i =0; i <=links.length; i++){

    downloaderThread = new DownloaderThread(thisActivity, links[i]);

    downloaderThread.start();
    }

You create 3 threads almost instantaneously. The field downloaderThread will contain a reference only to the last of these threads at the end. This means that all three will be accessing the parentActivity.activityHandler simultaneously, leaving him confused. Moreover, the activityHandler uses the field downloaderThread which will refer to the last thread, even if the code is activated by the other threads, resulting in one thread interfering with the other. Maybe (or maybe not) you have to create a Handler and a ProgressDialog by thread and pass the Handler as a parameter in the DownloaderThread instead of thisActivity.

  1. The limits of your for are wrong:
for(int i =0; i <=links.length; i++){

Because of that <=, the indexes will be 0 until 3, not 0 until 2. When trying to access links[i] where i = 3, you will get a ArrayIndexOutOfBoundsException.

  1. And here is your NullPointerException:
    String links[] = null;

    links[0] = "http://lwn.net/images/pdf/20040806_novell_mtd.pdf";
    links[1] = "http://lwn.net/images/pdf/IBM-155.pdf";
    links[2] = "http://lwn.net/images/pdf/IBM-148.pdf";

If links is null, links[0] is NullPointerException! What you wanted is this:

    String[] links = {
        "http://lwn.net/images/pdf/20040806_novell_mtd.pdf",
        "http://lwn.net/images/pdf/IBM-155.pdf",
        "http://lwn.net/images/pdf/IBM-148.pdf"
    };
  • in this case, as I declare the global variable, and fill in the links elsewhere?

  • @Warlock You can use a ArrayList.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.