Search code examples
javaandroidmultithreadingrunnablenetworkonmainthread

Android - Getting NetworkOnMainThreadException for file download even though download is started in separate thread


I am a bit confused with threading on Android, basically I want to download video file, but I am getting a NetworkOnMainThreadException.

MY setup is as follows, I have a VideoDownloader class that is there only to download a video. Its main method looks like this:

public void downloadVideoFile(Context context, String videoURL, String targetFileName) . This will open an http connection to the videoURL and save it to the file system using the context's openFileOutput method and the targetFileName as the name for the file. Nothing to consider about multithreading yet.

Then I am implementing a VideoDownloadTask which looks as follows:

public class VideoDownloadTask extends Thread {

  private VideoDownloader videoDownloader;

  public VideoDownloadTask(VideoDownloader videoDownloader){
    this.videoDownloader = videoDownloader;
  }

  @Override
  public void run() {
    videoDownloader.startDownload();
  }

  public void cancel(){
    Log.d(Constants.LOG, "DEBUG [" + getClass().getName() + "]: Cancel current downloaded in video downloader");
    videoDownloader.cancel();

  }
}

This class is supposed to start a video download in its own thread, given an instance of VideoDownloader during initialization.

Finally, in my activity I am executing the following method:

    private void initiateFileDownload() {

      Intent intent = getIntent();
      String seriesName = intent.getStringExtra("seriesName");
      String amazonKey = intent.getStringExtra("amazonKey");
      String videoURL = intent.getStringExtra("videoURL");

      URIGenerator uriGenerator = new URIGenerator();
      String targetFilePath = uriGenerator.buildTargetFilePath(seriesName, amazonKey);
      Log.d(Constants.LOG, "DEBUG [" + getClass().getName() + "]: Initiate file download to file: " + targetFilePath);

      VideoDownloader videoDownloader = new VideoDownloader(this, videoURL, targetFilePath);

      videoDownloadTask = new VideoDownloadTask(videoDownloader);
      videoDownloadTask.run();
    }

As I said in the beginning, this code throws a NetworkOnMainThreadException, but I am wondering why, because according to my understanding I am executing the video download in a separate thread (in the VideoDownloadTask), or am I wrong and the fact that I create the instance of the VideoDownloader on the main thread is enough to also make it run its method on the main thread, no matter if I am giving it to a separate thread?

Can anyone help me improve this piece of code so that the download is going to work?


Solution

  • Use start() to start a new thread. run() just runs the code in the current thread.