PDA

View Full Version : دانلود چند فایل در بکگراند



Nevercom
دوشنبه 29 آبان 1391, 22:09 عصر
سلام دوستان

من در یکی از اکتویتی های برنامه یک فایل XML رو Parse میکنم و لیست پکیج های موجود برای دانلود رو در یک ListView نمایش میدم، کنار هر آیتم یه CheckBox هست که کاربر میتونه انتخاب کنه کدوم پکیج ها دانلود بشن.

چندتا سوال در این زمینه دارم.
از چه روشی برای دانلود چند فایل استفاده کنم که برای API 7 هم جواب بده ؟
آیا کلاسی رو میشناسید که بتونه بصورت مطمئن دانلود فایل ها رو مدیریت کنه ؟
خودم تصمیم دارم از این کلاس استفاده کنم، اما در مورد کاراییش و اینکه فایل ها رو درست دانلود کنه (با توجه به حجیم بودن بعضی از پکیج ها و سرعت نه چندان مناسب اینترنت اپراتورهای موبایل):
package org.test.download;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.ProgressBar;

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"));
}

}

}

سوال بعد اینکه با فرض اینکه کاربر ۱۰ فایل برای دانلود انتخاب کرده، حالا راه درست برای دانلود چی هست (از لحاظ کد نویسی اصولی)، بهتره مثلاً لیست دانلود رو بصورت آرایه به کلاس پاس بدیم و اون عملیات دانلود فایل ها رو انجام بده ؟
چطور میشه به نحوی کلاس رو ویرایش کرد که خودش عملیات دانلود تعدادی فایل رو که بصورت آرایه بهش پاس دادیم مدیریت کنه ؟

و مورد بعد نحوه ی نمایش درصد پیشرفت هست. همین کلاس یک آرگومان میگیره که شئ ProgressBarی هست که درصد پیشرفت براش ارسال میشه.
ایده آل ی که دنبالشم چیزی شبیه به مدیریت دانلود برنامه ی بازار هست، رو همه ی ورژن ها ی اندروید جواب میده، اکتیویتی درصد پیشرفت خوب طراحی شده و در حین دانلود میشه از کاربرد های دیگه ی برنامه استفاده کرد (همین کلاس هم چون در یک ترد جداگانه اجرا میشه نباید وابسته به اکتیویتی خاصی باشه) و درصد پیشرفت رو در Notification Bar نمایش میده.

ممنون میشم راهنماییم کنید.

Nevercom
جمعه 03 آذر 1391, 19:01 عصر
هیچکدوم از دوستان تجربه ای در مبحث دانلود فایل ها و مدیریت دانلود ندارن ؟

Modernidea
یک شنبه 05 آذر 1391, 22:23 عصر
سلام

من فقط در حد اطلاعات کمی که دارم به بعضی از سوالاها جواب میدم!



آیا کلاسی رو میشناسید که بتونه بصورت مطمئن دانلود فایل ها رو مدیریت کنه ؟

کلاسی که خودتون معرفی کردید کلاس جمع جور و خوبیه به نظرم. من تجربه ای در باره دانلود نداشتم. توی این کلاس از AsyncTask استفاده شده و با این کار، شما هر دفعه که لینک دانلود رو به این کلاس بدید به طور همزمان با دیگر دانلود ها(درصورت وجود) شروع به دانلود میکنه و صبر نمیکنه تا دانلودی تمام بشه و بعدی رو شروع کنه.



با فرض اینکه کاربر ۱۰ فایل برای دانلود انتخاب کرده، حالا راه درست برای دانلود چی هست (از لحاظ کد نویسی اصولی)، بهتره مثلاً لیست دانلود رو بصورت آرایه به کلاس پاس بدیم و اون عملیات دانلود فایل ها رو انجام بده ؟

فکر نمیکنم فرقی بین اینکه با یک حلقه یا به صورت آرایه مقادیر را پاس بدید، وجود داشته باشه(دقیق نمیدونم).
اما با توجه به سرعت پایین اینترنت در ایران، فکر کنم بهتر این باشه که بعد از تمام شدن هر دانلود، دانلود بعدی شروع به کار کنه. برای این کار میشه از دو روش استفاده کرد یکی Handler و یکی BroadcastReceiver.
فرض کنید شما لیستی از دانلود ها را آماده کردید و آدرس اولی را به این کلاس میفرستید و بعد از تمام شدن آن دانلود، پیامی به Handler مربوطه میفرستید یا Broad Cast میکنید که برنامه متوجه بشه دانلود تموم شده. با دریافت این پیام چک میکنید که هنوز توی لیست چیزی برای دانلود مونده یا نه، دوباره سنارو رو از اول شروع کنید و آدرس لینک دانلود رو به کلاس میدید و ... .

در مورد Handler و BroadcastReceiver مطلب در اینترنت زیاده فقط یک سرچ کوچیک لازمه. من خودم این دو موضوع را هنوز خوب یاد نگرفتم چون یکم سنگینه و نیاز داره خوب دفت کنید و مطالعه کنید.
به عنوان مثال این آدرس (http://www.vogella.com/articles/AndroidPerformance/article.html) توضیحات کاملی داده شده: Android Threads, Handlers and AsyncTask - Tutorial (http://www.vogella.com/articles/AndroidPerformance/article.html)

hesamy2004
جمعه 10 آذر 1391, 19:01 عصر
هیچکدوم از دوستان تجربه ای در مبحث دانلود فایل ها و مدیریت دانلود ندارن ؟

اگر سر API 7 خیلی سرسخت نباشی و اون رو به ورژن 9 تغییر بدی میتوانی از کلاس DownloadManager استفاده کنی تا آن کلاس مدریت دانلود را برعهده بگیرد. نمونه کدی پیدا کردم که شاید راهنمای خوبی باشد.
Android DownloadManager Example (http://www.vogella.com/blog/2011/06/14/android-downloadmanager-example/)

dehghanimeh
جمعه 10 آذر 1391, 22:31 عصر
سلام
این مثال رو ببینید . وابستگی به نسخه اندروید نداره ، همزمان چند فایل رو دانلود میکنه و نمایش درصد دانلود هم داره
https://github.com/umeng/android_download_manager
موفق باشید