using one ASyncTask for several times Simultaneously - android

I have a program with one button click, when clicked, 4 Downloads should executed Simultaneously. I use ASyncTask class for this purpose with for iterator:
for(int i=0;i<downloadCounts;i++){
new DownloadTask().execute(url[i]);
}
but in running, only one download executed and all 4 progressbars show that single download.
I want to download 4 downloads in same time. how can I do?
for more details, my download manager, get a link and divide it to 4 chunks according to file size. then with above for iterator , command it to run 4 parts download with this class:
private class DownloadChunks extends AsyncTask<Long,String,String>{
#Override
protected void onPreExecute() {
super.onPreExecute();
setStatusText(-1);
}
#Override
protected String doInBackground(Long... params) {
long s1 = params[0];
long s2 = params[1];
int count;
try{
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Range", "bytes=" + s1 + "-" + s2);
connection.connect();
len2 = connection.getContentLength();
InputStream input = new BufferedInputStream(url.openStream(),8192);
File file = new File(Environment.getExternalStorageDirectory()+"/nuhexxxx");
if(!file.exists())file.mkdirs();
OutputStream output = new FileOutputStream(file+"/nuhe1.mp3");
byte[] data = new byte[1024];
long total = 0;
while ((count= input.read(data))!=-1){
total += count;
publishProgress(""+(int)((total*100)/len2));
output.write(data,0,count);
}
output.flush();
output.close();
input.close();
counter++;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
setStatusText(Integer.parseInt(values[0]));
}
#Override
protected void onPostExecute(String aVoid) {
super.onPostExecute(aVoid);
Log.e("This part is downloaded", "..." + len2 + " start with: " + counter);
}
}
All logs shows that every thing is OK and file is completely downloaded. but each chunk download separate and in order. I want to download chunks Simultaneously

Instead of just call the .execute() method of your AsyncTask, use this logic to achieve what you want:
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
} else {
new MyAsyncTask().execute(params);
}
Check more info from the official documentation of AsyncTask

Related

ProgressBar is not updating from AsyncTask

I'm using ProgressBar to try and display the progress of downloading and saving a file. The ProgressBar shows up, but stays at 0, until it closes when the task is finished. I've tried different approaches, but it just won't update. Is there something wrong with the code?
class downloadData extends AsyncTask<Void, Integer, Void>
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params)
{
int count;
try
{
URL url = new URL("http://google.com");
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
InputStream is = url.openStream();
File testDirectory = new File(MainActivity.this.getFilesDir(), "downloadedData.txt");
if (!testDirectory.exists())
{
testDirectory.mkdir();
}
FileOutputStream fos = new FileOutputStream(testDirectory+"/downloadedData.txt");
byte data[] = new byte[1024];
long total = 0;
while ((count = is.read(data)) != -1)
{
total += count;
int neki = (int)(((double)total/lenghtOfFile)*100);
this.publishProgress(neki);
fos.write(data, 0, count);
}
is.close();
fos.close();
}
catch (Exception e)
{
Log.e("ERROR DOWNLOADING","Unable to download" + e.getMessage());
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values)
{
super.publishProgress(values);
progressDialog.setProgress(values[0]);
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
progressDialog.dismiss();
}
}
onCreate
progressDialog = new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(true);
progressDialog.setMax(100);
progressDialog.setMessage("Downloading Data");
And when the button is clicked that starts the downloading: progressDialog.show();
Try to debug where the progress is calculated. It might be a cast problem, you can try to do it in 2 steps to avoid getting 0 after your division. But again you should create a variable with this progress value, put a breakpoint there and see the casting problem !
I am not sure what the problem might be in your code, but you have have a go at this progressDialog.incrementProgressBy(incrementValue);
This may sound a bit tard but have you tried to invalidate() the ProgressBar after you set the progress? I am not sure it does one automatically when you set the progress.
I was also facing the same problem and spent hours on it. The problem is in calculation of the progress value.
int neki = (int)(((double)total/lenghtOfFile)*100);
Instead you should do calculation in two steps:
int neki = total * 100;
neki = (int)(neki/lengthOfFile);
publishProgress(neki);
This solved my problem. Hope this will help.

How to use AsyncTask to download files? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm Using this class to download files:
public class DownloadService extends Service {
String downloadUrl;
LocalBroadcastManager mLocalBroadcastManager;
ProgressBar progressBar;
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/org.test.download/");
double fileSize = 0;
DownloadAsyncTask dat;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
public DownloadService(String url,Context c, ProgressBar pBar){
downloadUrl = url;
mLocalBroadcastManager = LocalBroadcastManager.getInstance(c);
progressBar = pBar;
dat = new DownloadAsyncTask();
dat.execute(new String[]{downloadUrl});
}
private boolean checkDirs(){
if(!dir.exists()){
return dir.mkdirs();
}
return true;
}
public void cancel(){
dat.cancel(true);
}
public class DownloadAsyncTask extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... params) {
String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/")+1);
if(!checkDirs()){
return "Making directories failed!";
}
try {
URL url = new URL(downloadUrl);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
fileSize = urlConnection.getContentLength();
FileOutputStream fos = new FileOutputStream(new File(dir,fileName));
InputStream inputStream = urlConnection.getInputStream();
byte[] buffer = new byte[500];
int bufferLength = 0;
int percentage = 0;
double downloadedSize = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 )
{
if(isCancelled()){
break;
}
fos.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
percentage = (int) ((downloadedSize / fileSize) * 100);
publishProgress(percentage);
}
fos.close();
urlConnection.disconnect();
} catch (Exception e) {
Log.e("Download Failed",e.getMessage());
}
if(isCancelled()){
return "Download cancelled!";
}
return "Download complete";
}
#Override
protected void onProgressUpdate(Integer... values){
super.onProgressUpdate(values[0]);
if(progressBar != null){
progressBar.setProgress(values[0]);
}else{
Log.w("status", "ProgressBar is null, please supply one!");
}
}
#Override
protected void onPreExecute(){
mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_STARTED"));
}
#Override
protected void onPostExecute(String str){
mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_FINISHED"));
}
#Override
protected void onCancelled(){
mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_CANCELLED"));
}
}
}
I'm using this because apparently DownloadManager wont work prior to API 9 and i'm targeting API 7
I have ListView which parses a XML File and shows packages that can be downloaded.
How can I modify this class to accept Array of strings containing URLs and download them one by one ?
Or is there any good way to download List of files ?
Look into using an IntentService. The thread in an IntentService runs in the background, which means you don't have to handle all the mess of thread handling.
IntentService kills off its thread once its done, so you have to persist the data.
To communicate back to your Activity, use a broadcast receiver.

android 2.1 AsyncTask file download not working for multiple thread work fine when call single instance

i am using android 2.1 ,api level 7 and try to implement asynchronous file download from LAN server
for this i am trying to implement AsyncTask .When i am trying to call a single thread it works find but when call multiple its just stop both the thread
/* AsyncTask class*/
class DownloadFileAsync extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
Log.i("count","in");
URLConnection conexion = url.openConnection();
Log.i("count","in1");
conexion.connect();
Log.i("count","in2");
File root = android.os.Environment.getExternalStorageDirectory();
Log.i("count","in3");
int lenghtOfFile = conexion.getContentLength();
Log.i("count","in4");
BufferedInputStream input = new BufferedInputStream(url.openStream());
Log.i("count","in5");
OutputStream output = new FileOutputStream(root.getAbsolutePath() + "/video" +aurl[1] +".mp4");
byte data[] = new byte[1024];
long total = 0;
Log.i("count","in6");
while ((count = input.read(data)) != -1) {
//Log.i("count","in7");
total += count;
Log.i("count",aurl[1]);
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.i("progress",progress[0]);
}
#Override
protected void onPostExecute(String unused) {
Log.i("process","end");
}
}
/*main method call*/
private void startDownload() {
Log.v("count","out");
String url = lanurl+"titanic/video"+1+"_en.m4v";
new DownloadFileAsync().execute(url,"1");
url = lanurl+"titanic/video"+2+"_en.m4v";
new DownloadFileAsync().execute(url,"2");
}
output :
download both file in sd card
but no file downloading properly
I didn't understand the complete Question. But seems like your problem is with AsyncTask.
Single Object created for an AsyncTask can be used only once. If you want to use it again, you need to create an another object for the same AsyncTask.

how to download a video and store in the database while showing the progress at the same time in android

Hoping you have a great day! I am stuck with a problem such that I am not able to show the progress of video download properly. The main idea is that I am downloading a video from the server and storing in the DB as blob. At the same time I am showing the actual progress of the file downloaded. The video download and the progress bar are working fine but I am not able to store it in the DB. I have used AsyncTask.doInBackground and AsyncTask.publishProgress methods respectively. Both are working fine. But it is not able to store in the DB.
The code is as follows:
public class DownloadVideoTask extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... url) {
String videoUrl = downloadAndStoreVideoInDB(url[0]);
return videoUrl;
//String videoUrl = downloadVideo(url[0]);
//return videoUrl;
}
protected void doProgress(int val){
publishProgress(val);
}
#Override
protected void onProgressUpdate(final Integer... values) {
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(values[0]);
if(progressBar.getProgress()>=progressBar.getMax()){
progressBar.setVisibility(View.INVISIBLE);
//Toast.makeText(VideoActivity.this, "Download Complete", Toast.LENGTH_SHORT).show();
syncBtn.setVisibility(View.INVISIBLE);
playBtn.setVisibility(View.VISIBLE);
}
/**
Runnable runnable = new Runnable(){
public void run(){
for(int i = 0; i <= values[0]; i++){
final int value = i;
try{
Thread.sleep(2000);
}catch(InterruptedException ie){
ie.printStackTrace();
}
handler.post(new Runnable(){
public void run(){
progressBar.setProgress(value);
if(progressBar.getProgress()>=progressBar.getMax()){
progressBar.setVisibility(View.INVISIBLE);
//Toast.makeText(VideoActivity.this, "Download Complete", Toast.LENGTH_SHORT).show();
syncBtn.setVisibility(View.INVISIBLE);
playBtn.setVisibility(View.VISIBLE);
}
}
});
}
}
};
new Thread(runnable).start();
*/
//super.onProgressUpdate(values);
}
//Downloads the video from the specified url.
public String downloadAndStoreVideoInDB(String path){
try {
Log.i(TAG , "URL " +path);
URL url = new URL(path);
URLConnection connection = url.openConnection();
int lengthOfFile = connection.getContentLength();
connection.connect();
InputStream videoStream = connection.getInputStream();
BufferedInputStream videoBufferedStream = new BufferedInputStream(videoStream,128);
ByteArrayBuffer videoByteArray = new ByteArrayBuffer(500);
//Percentage calculation for progress bar is pending.
//doProgress(10);
//Get the bytes one by one
int current = 0;
long total = 0;
//keeps on executing does not come out!
while((current = videoBufferedStream.read())!= -1){
total += current;
//Show the download progress
doProgress((int)((total*100)/lengthOfFile)); // here I show the progress
videoByteArray.append((byte)current);
//Log.i(TAG, String.valueOf(current));
}
//This code never reaches hence not able to insert in the DB
dbAdapter.insertVideoBytesInVideoDownloadsTable(id, videoByteArray.toByteArray());
//doProgress((int)((total*100)/lengthOfFile));
videoBufferedStream.close();
}catch (IOException ex) {
Log.e(TAG, "error: " + ex.getMessage(), ex);
ex.printStackTrace();
}
return path;
}
#Override
protected void onPostExecute(String result) {
}
}
You DONT store that kind of content into a database.. You store a LINK to that content.
Store video in local path(that is in sdcard or in phone memory) and store that local path in Database.When you want to play that video take local url from database and go to the local url path and play the video.

How to get back the task completion status in AsyncTask

This is related to my previous post Problem with downloading multiple files using AsyncTask
I'm trying to download two video files and also show a ProgressDialog during the process. For this I'm using AsyncTask. I want the 1st download to complete, free up memory then start the 2nd download. I wrote the following code to achieve this, but it seems the 2nd download never begins.
startDownload() {
DownloadFileAsync d1 = new DownloadFileAsync();
d1.execute(videoPath+fileNames[0],fileNames[0]);
if(d1.getStatus()==AsyncTask.Status.FINISHED) {
d1 = null;
DownloadFileAsync d2 = new DownloadFileAsync();
d2.execute(videoPath+fileNames[1],fileNames[1]);
}
}
Is there a way that I can get back the completion status of my 1st task & then start the 2nd ?
The following is the code of my DownloadFileAsync class:
class DownloadFileAsync extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
File root = android.os.Environment.getExternalStorageDirectory();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(root.getAbsolutePath() + "/videos/" + aurl[1]);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
tv.append("\n\nFile Download Completed!");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
}
}
As DKIT Android suggested, you could start the second download from onPostExecute, but only if for example download2 is null
#Override
protected void onPostExecute(String unused)
{
if (d2 == null)
{
d2 = new DownloadFileAsync();
d2.execute(videoPath+fileNames[1],fileNames[1]);
}
}
If you need to start more downloads, just write the method outside of your asynctask, which will check which download should be started next.
Start your second download from within your first onPostExecute-method.
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
tv.append("\n\nFile Download Completed!");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
// Here you start your new AsyncTask...
}
This code:
if(d1.getStatus()==AsyncTask.Status.FINISHED) {
d1 = null;
DownloadFileAsync d2 = new DownloadFileAsync();
d2.execute(videoPath+fileNames[1],fileNames[1]);
}
...will execute once, and immediately after the first AsyncTask is executed, thus it will always be false. If you want to go that route, you need to do it in a while loop - which kind of defeats the point of making the task Async in the first place.

Categories

Resources