Android 从文件服务器下载随机图像

Android 从文件服务器下载随机图像,android,imageview,download,Android,Imageview,Download,这是我的尝试。我的文件托管在我自己的服务器上,主要是JPGs文件。我正在尝试将它们下载到我的应用程序中。我无法将这些图像生成到我的应用程序中。我遵循这个博客的指南 我的xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:la

这是我的尝试。我的文件托管在我自己的服务器上,主要是JPGs文件。我正在尝试将它们下载到我的应用程序中。我无法将这些图像生成到我的应用程序中。我遵循这个博客的指南

我的xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView 
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, HTTPImage load test"
/>
<Button android:id="@+id/get_imagebt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get an image"
android:layout_gravity="center"
/> 
<ImageView android:id="@+id/imview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>

您的代码有几个问题:

  • 您正试图从UI线程执行网络操作(从远程服务器下载文件)网络操作必须从另一个线程执行。否则,将引发异常
从另一个线程启动代码的方法之一是:

new Thread(new Runnable() {

        @Override
        public void run() {
            downloadFile(imageUrl+i+".jpg");
        }
    }).start();
更好的方法是使用AsyncTask或IntentService(也在单独的线程上执行代码)

  • 第二件事——你不能仅仅用输入流的大小创建int数组:如果图像太大,它可能会失败。尝试将下载中断为固定大小的段(例如,每个段2058字节),例如:

    private HttpURLConnection conn;
    private InputStream stream;
    private FileOutputStream out;
    
    private double fileSize;
    private double downloaded;
    
    
    public void downloadFile(String fileURL, String fileName) {
    try {
    
        conn = (HttpURLConnection) new URL(fileURL).openConnection();
        fileSize = conn.getContentLength();
        File file = new File(fileName);
    
        out = new FileOutputStream(file);
        conn.connect();
    
        stream = conn.getInputStream();
    
        while (status == DOWNLOADING) {
            byte buffer[];
    
            if (fileSize - downloaded > MAX_BUFFER_SIZE) {
                buffer = new byte[MAX_BUFFER_SIZE];
            } else {
                buffer = new byte[(int) (fileSize - downloaded)];
            }
            int read = stream.read(buffer);
    
            if (read == -1) {
    
                out.close();
                if (conn != null) {
                    conn.disconnect();
                }
    
                break;
            }
    
            out.write(buffer, 0, read);
            downloaded += read;
        }
    
    } catch (Exception e) {
        Log.e("downloadFile():", e.getMessage());
        if (conn != null) {
            conn.disconnect();
        }
    }
    
    }
    

您的代码有几个问题:

  • 您正试图从UI线程执行网络操作(从远程服务器下载文件)网络操作必须从另一个线程执行。否则,将引发异常
从另一个线程启动代码的方法之一是:

new Thread(new Runnable() {

        @Override
        public void run() {
            downloadFile(imageUrl+i+".jpg");
        }
    }).start();
更好的方法是使用AsyncTask或IntentService(也在单独的线程上执行代码)

  • 第二件事——你不能仅仅用输入流的大小创建int数组:如果图像太大,它可能会失败。尝试将下载中断为固定大小的段(例如,每个段2058字节),例如:

    private HttpURLConnection conn;
    private InputStream stream;
    private FileOutputStream out;
    
    private double fileSize;
    private double downloaded;
    
    
    public void downloadFile(String fileURL, String fileName) {
    try {
    
        conn = (HttpURLConnection) new URL(fileURL).openConnection();
        fileSize = conn.getContentLength();
        File file = new File(fileName);
    
        out = new FileOutputStream(file);
        conn.connect();
    
        stream = conn.getInputStream();
    
        while (status == DOWNLOADING) {
            byte buffer[];
    
            if (fileSize - downloaded > MAX_BUFFER_SIZE) {
                buffer = new byte[MAX_BUFFER_SIZE];
            } else {
                buffer = new byte[(int) (fileSize - downloaded)];
            }
            int read = stream.read(buffer);
    
            if (read == -1) {
    
                out.close();
                if (conn != null) {
                    conn.disconnect();
                }
    
                break;
            }
    
            out.write(buffer, 0, read);
            downloaded += read;
        }
    
    } catch (Exception e) {
        Log.e("downloadFile():", e.getMessage());
        if (conn != null) {
            conn.disconnect();
        }
    }
    
    }
    

您需要使用
AsyncTask
来执行此操作。阅读并查看此内容。您需要使用
AsyncTask
来执行此操作。阅读并看到这个。谢谢塔尔·卡内尔。您提到的上述代码将仅从写在字符串(URL)上的特定URL获取图像。我想列出一系列定期更新/更改的url,而无需在每次有新图像时修改代码。我使用字符串imageUrl=“”;因此,我可以列出我的web服务器中以.jpg结尾的所有图像。请帮助我。我想做的是,我想从我的web服务器加载100++图像(URL类似于此),而不指定字符串中的每个图像URL。@kcchai:如果您想从服务器获取随机数据(不指定特定的资源/图像)然后,服务器负责随机为您提供特定的资源。我看不出你的应用程序有任何方式可以请求随机资源,而不知道服务器上可以有什么选项(映像名/确切映像路径)@kcchai:如果你的服务器是FTP服务器,我猜有一个函数可以返回指定路径(目录)下的所有文件,如果你想下载特定目录下的所有文件,然后你可以迭代每个文件,得到他的名字,然后下载它。我将给出一个场景,我的应用程序在mystrings.xml中有大约10个图像URL。然后我把它上传到google play上。第二天,我又在我的应用程序中添加了10张新图片。是否需要将新图像URL添加到my strings.xml中?然后再次上传到google play market。谢谢Tal Kanel。您提到的上述代码将仅从写在字符串(URL)上的特定URL获取图像。我想列出一系列定期更新/更改的url,而无需在每次有新图像时修改代码。我使用字符串imageUrl=“”;因此,我可以列出我的web服务器中以.jpg结尾的所有图像。请帮助我。我想做的是,我想从我的web服务器加载100++图像(URL类似于此),而不指定字符串中的每个图像URL。@kcchai:如果您想从服务器获取随机数据(不指定特定的资源/图像)然后,服务器负责随机为您提供特定的资源。我看不出你的应用程序有任何方式可以请求随机资源,而不知道服务器上可以有什么选项(映像名/确切映像路径)@kcchai:如果你的服务器是FTP服务器,我猜有一个函数可以返回指定路径(目录)下的所有文件,如果你想下载特定目录下的所有文件,然后你可以迭代每个文件,得到他的名字,然后下载它。我将给出一个场景,我的应用程序在mystrings.xml中有大约10个图像URL。然后我把它上传到google play上。第二天,我又在我的应用程序中添加了10张新图片。是否需要将新图像URL添加到my strings.xml中?然后再次上传到google play market。