如何从服务器下载系列图像
How to download the series of Images from Server
我有自己的服务器,我想自动一张一张下载图片。
现在我尝试的是下载图像并将其保存在设备上,并且 100% 完美地工作。但这适用于单个图像,这里是好的 link。但它正在工作,但只下载一张图片,或者你可以说一张图片换一张 link 。
我想到了这个想法,那就是制作 Url 的字符串数组,然后应用 for 循环,然后它会下载并执行那么多 Asynctask。
但这不是一个好的做法,因为它会启动太多的异步任务。
我想要的
我想要如果我有 10 Url ,那么它应该从
第一个 url 到最后一个 url 但一个接一个,我的意思是当 First Image 有
已经下载然后它应该在保存后开始第二张图片
设备上的第一张图片。
所有图片应该统一显示进度条进度。并且应该更新进度假设有 10 张图像,那么当第一张图像成功下载时它应该显示 10% 完成,如果已经下载 2 张图像它应该显示 20%。
请给我源代码或任何可以帮助我的东西。谢谢。
如果您的单个下载已经达到 运行,那么对多个图像进行链接下载会有什么问题?如果您不关心精确的进度(至少这是我在这里的理解),您可以简单地通过 for 循环来完成。
伪代码:
String[] urlStack = {"http://www.myimage.com/1.jpg", "http://www.myimage.com/2.jpg", "http://www.myimage.com/3.jpg"};
for(int i = 0; i < urlStack.length; i++)
{
yourAlreadyDoneDownloadProcedure(updateProgressCallback);
}
...
下载完成后,当然会在下载过程中调用 updateProgressCallback 方法。
...
private void updateProgressFallback()
{
progressBarText += 100 / urlStack.length;
}
这只是为了演示您可以/应该如何处理这个问题。
编辑您的第一条评论:
在这种情况下,您应该使用 FutureTask。
FutureTask 对象可以等待完成,没有任何 while()...sleep
例如
for(int i = 0; i < urlStack.length; i++)
{
// fTask is an array of your download procedure objects
// get() will wait until the Task is done, no manual sleep commands necessary
fTask[i].get();
// since we have a concatenation of downloads, we can update progress here
progessBarText += 100 / urlStack.length;
}
编辑您的第二条评论:
您将拥有一个实现 Callable
的 Class,您所有的魔法都在这里发生:
public class MyCallable implements Callable<String>
{
String url;
public MyCallable(String s)
{
url = s;
}
@Override
public String call() throws Exception
{
// Download image here, you have the URL stored in `url`
return "I'm done";
}
}
您的 FutureTask 然后运行该对象:
MyCallable img1 = new MyCallable("http://www.myimage.com/1.jpg");
MyCallable img2 = new MyCallable("http://www.myimage.com/2.jpg");
FutureTask<String> fTask = new FutureTask<String>(img1);
fTask.get();
fTask = new FutureTask<String>(img2);
fTask.get();
这样是不是更清楚了?上面的代码可以优化很多,这只是为了了解你需要了解的FutureTask
你为什么不在 aysncTask 中尝试这个 for 循环,因为这不会创建多个 aysncTask 对象,内存使用更少。
public class httpDownloadImages extends AsyncTask<Void,Void,String> {
Bitmap myBitmap[]=new Bitmap[10];
@Override
protected void onPreExecute() {
super.onPreExecute();
showProgressDialog();
}
@Override
protected String doInBackground(Void... params) {
try {
for(int i=1; i<=10; i++){
String src="http://"+ip+"/images/"+i+".jpg";
java.net.URL url = new java.net.URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
myBitmap[i] = BitmapFactory.decodeStream(input);
if(myBitmap[i]!=null)
saveimagetoFile(myBitmap[i],i);
}
} catch (IOException e) {
return null;
}
return "successful";
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progress_dialog.hide();
}
}
如果需要,定义将图像保存到 SD 卡的方法:
void saveimagetoFile(Bitmap bmp,int num){
try {
String path = Environment.getExternalStorageDirectory().toString();
OutputStream fOut = null;
File file = new File(path, "PriceChecker/pc"+num+".jpg"); // the File to save to
fOut = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fOut); //save image to jpeg file
fOut.flush();
fOut.close();
}catch (Exception e){
}
}
但在我的例子中,图像名为 1.jpg 、 2.jpg、3.jpg ...等
希望这有帮助
编辑:
显示进度对话框的方法:
private void showProgressDialog(){
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
View promptView;
LayoutInflater layoutInflater = LayoutInflater.from(OrderActivity_gridstyle.this);
promptView = layoutInflater.inflate(R.layout.progress_dialog, null);
alertDialogBuilder.setView(promptView);
alertDialogBuilder.setCancelable(true);
progress_dialog=alertDialogBuilder.create();
progress_dialog.show();}
我使用的进度对话框的形状是:wheel,当然你可以使用不同的形状或类型。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:id="@+id/progress_time">
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="150dp"
android:layout_height="150dp"
android:id="@+id/prog_circle"
android:max="100"
android:progress="0"
android:indeterminate="true"
android:indeterminateDrawable="@drawable/progress_wheel"
android:layout_below="@+id/textView11"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Please Wait"
android:id="@+id/textView11"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textColor="@color/blue_" />
</RelativeLayout>
看起来像这样:
我有自己的服务器,我想自动一张一张下载图片。 现在我尝试的是下载图像并将其保存在设备上,并且 100% 完美地工作。但这适用于单个图像,这里是好的 link。但它正在工作,但只下载一张图片,或者你可以说一张图片换一张 link 。
我想到了这个想法,那就是制作 Url 的字符串数组,然后应用 for 循环,然后它会下载并执行那么多 Asynctask。
但这不是一个好的做法,因为它会启动太多的异步任务。
我想要的
我想要如果我有 10 Url ,那么它应该从 第一个 url 到最后一个 url 但一个接一个,我的意思是当 First Image 有 已经下载然后它应该在保存后开始第二张图片 设备上的第一张图片。
所有图片应该统一显示进度条进度。并且应该更新进度假设有 10 张图像,那么当第一张图像成功下载时它应该显示 10% 完成,如果已经下载 2 张图像它应该显示 20%。
请给我源代码或任何可以帮助我的东西。谢谢。
如果您的单个下载已经达到 运行,那么对多个图像进行链接下载会有什么问题?如果您不关心精确的进度(至少这是我在这里的理解),您可以简单地通过 for 循环来完成。
伪代码:
String[] urlStack = {"http://www.myimage.com/1.jpg", "http://www.myimage.com/2.jpg", "http://www.myimage.com/3.jpg"};
for(int i = 0; i < urlStack.length; i++)
{
yourAlreadyDoneDownloadProcedure(updateProgressCallback);
}
... 下载完成后,当然会在下载过程中调用 updateProgressCallback 方法。 ...
private void updateProgressFallback()
{
progressBarText += 100 / urlStack.length;
}
这只是为了演示您可以/应该如何处理这个问题。
编辑您的第一条评论:
在这种情况下,您应该使用 FutureTask。
FutureTask 对象可以等待完成,没有任何 while()...sleep
例如
for(int i = 0; i < urlStack.length; i++)
{
// fTask is an array of your download procedure objects
// get() will wait until the Task is done, no manual sleep commands necessary
fTask[i].get();
// since we have a concatenation of downloads, we can update progress here
progessBarText += 100 / urlStack.length;
}
编辑您的第二条评论:
您将拥有一个实现 Callable
的 Class,您所有的魔法都在这里发生:
public class MyCallable implements Callable<String>
{
String url;
public MyCallable(String s)
{
url = s;
}
@Override
public String call() throws Exception
{
// Download image here, you have the URL stored in `url`
return "I'm done";
}
}
您的 FutureTask 然后运行该对象:
MyCallable img1 = new MyCallable("http://www.myimage.com/1.jpg");
MyCallable img2 = new MyCallable("http://www.myimage.com/2.jpg");
FutureTask<String> fTask = new FutureTask<String>(img1);
fTask.get();
fTask = new FutureTask<String>(img2);
fTask.get();
这样是不是更清楚了?上面的代码可以优化很多,这只是为了了解你需要了解的FutureTask
你为什么不在 aysncTask 中尝试这个 for 循环,因为这不会创建多个 aysncTask 对象,内存使用更少。
public class httpDownloadImages extends AsyncTask<Void,Void,String> {
Bitmap myBitmap[]=new Bitmap[10];
@Override
protected void onPreExecute() {
super.onPreExecute();
showProgressDialog();
}
@Override
protected String doInBackground(Void... params) {
try {
for(int i=1; i<=10; i++){
String src="http://"+ip+"/images/"+i+".jpg";
java.net.URL url = new java.net.URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
myBitmap[i] = BitmapFactory.decodeStream(input);
if(myBitmap[i]!=null)
saveimagetoFile(myBitmap[i],i);
}
} catch (IOException e) {
return null;
}
return "successful";
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progress_dialog.hide();
}
}
如果需要,定义将图像保存到 SD 卡的方法:
void saveimagetoFile(Bitmap bmp,int num){
try {
String path = Environment.getExternalStorageDirectory().toString();
OutputStream fOut = null;
File file = new File(path, "PriceChecker/pc"+num+".jpg"); // the File to save to
fOut = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fOut); //save image to jpeg file
fOut.flush();
fOut.close();
}catch (Exception e){
}
}
但在我的例子中,图像名为 1.jpg 、 2.jpg、3.jpg ...等 希望这有帮助
编辑: 显示进度对话框的方法:
private void showProgressDialog(){
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
View promptView;
LayoutInflater layoutInflater = LayoutInflater.from(OrderActivity_gridstyle.this);
promptView = layoutInflater.inflate(R.layout.progress_dialog, null);
alertDialogBuilder.setView(promptView);
alertDialogBuilder.setCancelable(true);
progress_dialog=alertDialogBuilder.create();
progress_dialog.show();}
我使用的进度对话框的形状是:wheel,当然你可以使用不同的形状或类型。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:id="@+id/progress_time">
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="150dp"
android:layout_height="150dp"
android:id="@+id/prog_circle"
android:max="100"
android:progress="0"
android:indeterminate="true"
android:indeterminateDrawable="@drawable/progress_wheel"
android:layout_below="@+id/textView11"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Please Wait"
android:id="@+id/textView11"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textColor="@color/blue_" />
</RelativeLayout>
看起来像这样: