2

I am a new to Android programming and working on an app in which I want to store an image from an URL to the SD card when the user taps a button.

I found a method for it and used it but it throws NetworkOnMainThread exceptions causing the app to crash. What am I doing wrong?

Here's my code:

void DownloadPost(){
        try
        {
            URL url = new URL( mPost.postImagePath);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setDoOutput(true);
            urlConnection.connect();
            File SDCardRoot = Environment.getExternalStorageDirectory().getAbsoluteFile();
            String filename="downloadedFile.png";
            Log.i("Local filename:",""+filename);
            File file = new File(SDCardRoot,filename);
            if(file.createNewFile())
            {
                file.createNewFile();
            }
            FileOutputStream fileOutput = new FileOutputStream(file);
            InputStream inputStream = urlConnection.getInputStream();
            int totalSize = urlConnection.getContentLength();
            int downloadedSize = 0;
            byte[] buffer = new byte[1024];
            int bufferLength = 0;
            while ( (bufferLength = inputStream.read(buffer)) > 0 )
            {
                fileOutput.write(buffer, 0, bufferLength);
                downloadedSize += bufferLength;
                Log.i("Progress:","downloadedSize:"+downloadedSize+"totalSize:"+ totalSize) ;
            }
            fileOutput.close();
           Toast.makeText(PostListItem.this.getContext(),"Post saved to gallery",Toast.LENGTH_SHORT).show();
        }
        catch (MalformedURLException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
          //  filepath=null;
            e.printStackTrace();
        }
       // Log.i("filepath:"," "+filepath) ;
    }
blubb
  • 9,510
  • 3
  • 40
  • 82
sulphuric Acid
  • 585
  • 6
  • 23

4 Answers4

2

You can not run network request main thread.

       AsyncTask asyncTask=new AsyncTask() {
            @Override
            protected Object doInBackground(Object[] params) {
               DownloadPost();
            }
        };
        asyncTask.execute();

Or use Thread :

Thread thread = new Thread(new Runnable()
{
    @Override
    public void run() 
    {
        try 
        {
             DownloadPost();
        } 
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
});

thread.start(); 
Ahmad Aghazadeh
  • 16,571
  • 12
  • 101
  • 98
1

You should use an AsyncTask:

AsyncTask<Void, Void, Boolean> asyncTask = new AsyncTask<Void, Void, Boolean>() {


    @Override
    protected Boolean doInBackground(Void... params) {
        return DownloadPost();
    }

    @Override
    protected void onPostExecute(Boolean aBoolean) {
        super.onPostExecute(aBoolean);

        if (aBoolean)
            // UI Positive feedback
        else
            // UI Negative feedback
    }
};

make sure Download() return a boolean result to manage a feedback in onPostExecute().

doInBackground() to business logic (not UI) , onPostExecute() work on the UI thread

mcatta
  • 481
  • 5
  • 12
0

Actually you are calling DownloadPost from Main thread like onCreate or onResume. Make one AsyncTask and call DownloadPost method from doInBackGround method.

Android doesn't not allowed any network operation from main thread for that you have to call it from background.

Hope this will help you.

Amy
  • 4,034
  • 1
  • 20
  • 34
0

The exception that is thrown when an application attempts to perform a networking operation on its main thread.

This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged. See the document Designing for Responsiveness

Also see StrictMode.

Rocco
  • 110
  • 5