【问题标题】:Loading Lots Of Images From Server In Android在 Android 中从服务器加载大量图像
【发布时间】:2017-11-26 13:05:39
【问题描述】:

编辑 2: 即使在赏金之后,也没有人能给出完整的解决方案。所以我自己解决了。我已经在下面发布了我的解决方案。

我在谷歌上搜索了一下,也发现了各种不错的结果。但由于我不是服务器和后端术语方面的专家,我想在一个单独的问题中问它。我有一个网站托管,可以帮助我运行机构的网站。

  1. 在我的 android 应用程序中,应该有一个选项,例如“照片库”,它显示来自我的网站的图像(我在文件夹中上传图像)。我认为可以通过管理一些 JSON 文件来完成。

  2. 假设有一个文件夹 \public_html\MyApp\Images,其中包含“Event1”、“Event2”等文件夹。我将图像上传到这些不同的文件夹,我的 Android 应用应该会加载它们(可能会单独让用户选择一个文件夹)。

有可能吗?如果需要任何高级数据库系统,请给我一些介绍链接。有没有办法自动生成包含图像链接的 JSON?

编辑:我最近购买了用于后端之类的网站托管,但我还没有编写任何服务器端脚本或任何东西。这就是为什么需要详细回答的原因。我不知道如何管理这些图像,只需上传图像并将链接放入 JSON 或使用一些 MySQL、SQL 或任何我从未使用过的术语。

【问题讨论】:

  • 手动添加链接到db或上传图片并生成链接
  • 不要将上传文件夹放在公共区域,而是让您的应用程序调用一个带有参数的页面,检查文件是否存在,如果存在,则将其服务器化,如果不是,404 的
  • 我认为这是个问题。我是服务器类的新手。任何帮助链接将不胜感激。编辑:你的意思是 PHP 类型的文件?这是更好的方法还是比目前的方法更好?

标签: java php android json


【解决方案1】:

您可以通过Picasso库的帮助以JSON格式从服务器获取所有图像的路径并通过传递路径来显示图像 -

Picasso.with(context).load("imagepath").placeholder(R.drawable.placeholder)

.error(R.drawable.placeholder_error).into(imageView);

【讨论】:

    【解决方案2】:

    我自己找到了解决方案。它很容易理解和实现,只需要 JSON 的知识。首先,从我的网站目录中查看这张图片:

    “event1”、“event2”文件夹是专辑名称。我们可以根据需要创建任意数量。

    getfolders文件很重要。内容:

    {
       "test":[
          {
             "sub":"event1",
             "content":"https://i1.wp.com/www.downloadinformer.com/wp-content/uploads/2017/03/AMPFB.jpg?w=1366",
             "param":"1.php"
          },
          {
             "sub":"event2",
             "content":"myimageurl",
             "param":"myphpfilenamewithextension"
          }
       ]
    }
    

    我们在此处存储专辑名称,您可以在“子”字段中看到。 “content”字段包含指向专辑缩略图的链接,“param”包含相应 PHP 文件的名称。不用担心,您不需要学习 PHP。这是一个现成的脚本。

    1.php

    <?php
    
    $indir = array_filter(scandir('event1'), function($item) {
            return $item[0] !== '.';
    });
    
    echo json_encode($indir);
    ?>
    

    这个 PHP 文件有什么作用? 它列出了指定文件夹中存在的所有文件的名称。如您所见,我们已将“event1”指定为该 PHP 文件中的文件夹名称。因此它将以 JSON 格式返回所有图像的名称。不要忘记在“getfolders”文件的“param”字段中指定这个 PHP 文件。

    好的。所以这是一种算法。如果您有一些困惑,请重新阅读。现在我将展示一些代码。

    我做了两个活动(不喜欢片段)。一个显示相册,第二个显示其中的图像。

    Activity 1-> 解析 getfolders 文件并检索我们之前指定的相册。

    专辑标题:上述 JSON 的 sub 字段 , 专辑缩略图:上述 JSON 的 content 字段 ,(对用户隐藏)图像名称列表:param 字段

    因此,我们可以使用此信息在 Recyclerview 中显示它。现在我们为其项目指定 OnClickListener。

    On Click Of An Item-> 使用 Intent 启动第二个活动并传递专辑名称,该名称本质上是我们服务器上的文件夹名称。因此,我们可以访问包含图像的文件夹。同时传递“参数”字段值。这给了我们一个网址“www.mywebsite.com/..../alreadyspecifieddirectory/1.php”

    Activity->2 实现一个 GridLayoutManager 向用户显示图片。使用getIntent() 检索先前传递的值。首先,我们需要执行这个 PHP 文件并解析 JSON 内容。这是一些代码:

     private void loadJSON(){
            StringRequest stringRequest = new StringRequest(Request.Method.GET,
                    URL_DATA,
                    new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response) {
                            try {
                                JSONObject jsonObject = new JSONObject(response);
                                for (int i=2; i<jsonObject.length()+2;i++){
                                    String value =jsonObject.getString(String.valueOf(i));
                                    if (value.length()!=0) {
                                        ListItem item = new ListItem(value, mParam1+"/"+value, "nothing");
                                        listItems.add(item);
                                    }
                                }
                                adapter = new PhotoLibraryAdapter(Photos.this,listItems,photosList,true);
                                photosList.setAdapter(adapter);
                                progressBar.setVisibility(View.GONE);
                            } catch (Exception e) {progressBar.setVisibility(View.GONE);}
                        }
                    }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    progressBar.setVisibility(View.GONE);
                }
            });
            RequestQueue requestQueue = Volley.newRequestQueue(this);
            requestQueue.add(stringRequest);
        }
    

    请注意,我们从 2 开始 for 循环,因为 PHP 文件从索引 2 返回值,因为值 0 和值 1 是废值并命名为“。”和“..”分别。

    因此我们得到了可以通过 url 传递的图像名称: "www.mywebsite.com/.../albumnameretrieveedearlier/imagenamegivenbyPHPfile"

    并将其传递给适配器,以便我们可以使用 Picasso 库加载图像。

    就是这样!如果您有任何问题,请随时在 cmets 中提问。

    编辑 1: 外观如下:

    【讨论】:

      【解决方案3】:

      我建议您考虑以下两种文件服务和存储选项:

      1. Overview of Blobstore API for Java
      2. Google Cloud Storage

      【讨论】:

        【解决方案4】:

        请看,如果您在托管程序上拥有托管帐户,您将可以选择创建自己的数据库,甚至无需编写一行 mysql 代码。 对于服务器端,你需要学习 PHP。 此外,从不建议将图像存储在数据库中。 将它们存储在托管站点上的存储目录中,并将它们的链接(URL)存储在数据库中。这样可以更快地获取图像。

        对于 android 端,只需使用 Picasso 库即可节省您从服务器加载图像的时间和空间。

        你们都准备好了。 :) 评论查询。

        【讨论】:

          【解决方案5】:

          看起来,您需要 2 个新的数据库表。一个用于存储您的相册,另一个用于存储单个图像。

          CREATE TABLE `album` (
             `album_id` INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
             `album_name` VARCHAR(255) NOT NULL,
             `album_date` DATE NOT NULL);
          

          album 将存储所有专辑元数据,因此它将存储 Event1 及其详细信息、Event2 等等..

          CREATE TABLE `images` (
             `image_id` INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
             `album_id` INT(11) NOT NULL,
             `image_date` DATE NOT NULL,
             `image_path` VARCHAR(255) NOT NULL,
          FOREIGN KEY (album_id) REFERENCES album(album_id));
          

          images 将使用album_id 作为外键存储所有图像及其路径和所属专辑

          您对所有图片的查询将是

          SELECT * FROM `images`;
          

          特定相册中的图像将被查询为

          SELECT * FROM `images` WHERE `album_id` = *YOUR_ID*;
          

          SQL 查询的输出可以使用 JSON 编码

          json_encode($query_result); //PHP code
          

          编辑Gallery App Example On Android Hive

          您似乎将图像作为 BLOB 直接保存到数据库中,因此它为您提供了 64kb 的限制。最好保存图像的路径。 如果这不可能,则 base64 对图像进行编码并将它们存储在 VARCHAR 类型的列中。

          【讨论】:

          • 关于如何实现它的任何说明,在哪里?我假设您没有在帖子中看到我的编辑。
          • 你的主机有cpanel吗?使用 cpanel 进入 phpmyadmin 并在那里创建一个带有表的数据库。
          • 是的,但仅限于一个数据库,我似乎无法编辑它
          • 是的,您只需要一个数据库。您必须在该数据库中添加表。
          • 好的。我可以上传图片,但它限制为 64 KB。有什么想法可以增加这个限制吗?然后在它之后,如何在应用程序中进行。请编辑您的答案以获取完整说明。
          【解决方案6】:

          此方案不需要数据库。

          PHP 中需要两个 API 端点

          上传图片/api/upload

          <?php
          
          $target_dir = "uploads/";
          $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
          $uploadOk = 1;
          $imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
          // Check if image file is a actual image or fake image
          if(isset($_POST["submit"])) {
              $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
              if($check !== false) {
                  echo "File is an image - " . $check["mime"] . ".";
                  $uploadOk = 1;
              } else {
                  echo "File is not an image.";
                  $uploadOk = 0;
              }
          }
          // Check if file already exists
          if (file_exists($target_file)) {
              echo "Sorry, file already exists.";
              $uploadOk = 0;
          }
          // Check file size
          if ($_FILES["fileToUpload"]["size"] > 500000) {
              echo "Sorry, your file is too large.";
              $uploadOk = 0;
          }
          // Allow certain file formats
          if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
          && $imageFileType != "gif" ) {
              echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
              $uploadOk = 0;
          }
          // Check if $uploadOk is set to 0 by an error
          if ($uploadOk == 0) {
              echo "Sorry, your file was not uploaded.";
          // if everything is ok, try to upload file
          } else {
              if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
                  echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
              } else {
                  echo "Sorry, there was an error uploading your file.";
              }
          }
          ?>
          
          1. 列出图片

          先列出上传目录下的所有目录:

          $array = glob("uploads/*", GLOB_ONLYDIR);
          echo json_encode($array);
          
          1. 如果您想要一个特定的文件夹,您可以通过发送文件夹名称并附加到请求 URL 并列出所有文件来实现。

            $array = glob("上传/".$_REQUEST['dir']."/*"); echo json_encode($array);

          编辑

          // provides the current working directory
          echo getcwd() ."\r\n";
          // then navigate to path
          // glob(getcwd() . DIRECTORY_OF_IMAGES));
          // GLOB_BRACE tells to find all extensions in the brace
          $array = glob(getcwd() . "/web/bundles/img/*.{jpg,gif,png}", GLOB_BRACE);
          

          阅读这篇文章http://php.net/manual/en/function.glob.php

          【讨论】:

          • 将这些文件上传到一个文件夹并从应用程序调用它们?
          • 是的。如果您不想使用框架 (MVC) 代码,您可以创建一个像 upload.php 和 list.php(第 2 部分)这样的 php 文件。
          • @ParasSidhu,你想怎么上传文件?使用 android Java 代码还是 HTML?
          • 我可以直接通过FTP上传。这对我来说是最有效的方法......那么这些文件将以什么形式返回数据。抱歉,我是新手,非常希望实现此功能
          • 通过类似客户端的 FileZilla 的 FTP
          【解决方案7】:

          blob 类型可以不同。一方面,他可以指sql blob type。 最重要的是 MIME 类型like here

          如果您使用 Java 编写 API / 后端,则将图像流式传输到请求 blob 的客户端可能如下所示:

          public javax.ws.rs.core.Response exportBlob( String blobName ) throws Exception
          {
            Blob imageBlob = resultSet.getBlob(yourBlobColumnIndex); //query the blob from the Database
            String type = "image/png"; // Set your needed MIME Type
            StreamingOutput data = createStreamingOutput( imageBlob ); // stream it as a binary
            return Response.ok( data, type ).build();
          }
            /**
             * Creates an Outputstream of the Data from the given Blob.
             *
             * @param blob the blob that needs to be converted.
             * @return Outputstream of the Blob Data.
             * @throws WebApplicationException when the conversion failed.
             */
            private static StreamingOutput createStreamingOutput( final java.sql.Blob blob )
            {
              return output -> {
                try ( InputStream stream = blob.getBinaryStream() )
                {
                      byte[] buff = new byte[4096];
                      int count;
                      while ( ( count = stream.read( buff ) ) != -1 )
                      {
                         if ( count > 0 )
                        {
                          output.write( buff, 0, count );
                        }
                     }
                }
                catch ( SQLException e )
                {
                  throw new WebApplicationException( e.getMessage(), e );
                }
              };
            }
          

          将其转换为 Base64 也是一种选择。您必须适应您可以在 android 中使用的内容才能再次将此 binaryData 转换回图像。

          android 的一个例子可能是这样的:

          //byteArray is what you recieved from the API in this example
          Bitmap bm = BitmapFactory.decodeByteArray(byteArray, 0 ,byteArray.length);
          

          编辑:

          既然你说你对这种场景知之甚少,让我补充一些资源。

          1. 如何在 MySQL 数据库中保存实际图像here(这与其他数据库没有什么不同,除了语法)
          2. 在 php here 处处理 BLOB 的一个有点令人困惑的示例
          3. 在 Java 中处理 BLOB 的示例here

          经常有关于使用 BLOB 保存图像的讨论。只需在数据库中添加图像的 base64 表示,就可以让生活变得非常轻松。这样您就不需要处理 dataType BLOB。但是,我个人通常不喜欢该解决方案,而是更喜欢使用 BLOB。 (我已经添加了一篇关于blob的文章,所以我不会再写了)

          这里还有一些用于进入后端开发的链接,但这是您自己努力的部分。有很多东西要学,但不要害怕。一旦你完成了你的基础,它会变得更简单。

          Java Frameworks

          Interesting PHP Frameworks

          PHP Backend Tutorial

          Online course

          祝你旅途愉快!

          【讨论】:

            【解决方案8】:

            您尝试在 base64 中编码所有图像,然后插入数据库,然后创建从数据库中获取所有图像的 api,然后将您的 android 应用程序与此 api 同步并将图像作为 sqlite 存储在本地数据库中。 1.主要的好处是现在你也可以离线加载你的画廊图片

            【讨论】:

            • 任何链接或教程?
            【解决方案9】:

            是的,你真的可以做到这一点,这是可能的,也很实用,因为你有一个服务器。首先要做的是用这个 api 制作一个 API,您可以制作 android 可以从中获取 JSON 数据的 URL 作为对象,这意味着您还必须将图像路径转换为 ​​JSON。这个很棒的教程解释了这个过程的所有内容,甚至更多。由于您正在加载大量数据,我建议您使用 Picasso 进行图像缓存以及回收器视图

            https://www.simplifiedcoding.net/android-programming-tutorial-to-get-all-images-from-server/

            编码愉快!

            【讨论】:

            • 问题是我的服务器只允许 1 个 MySQL 数据库,而且我似乎无法添加图片。
            【解决方案10】:

            抱歉英语不好...

            这些图像在您的数据库中保存为 Blob 类型,或者您保存了某种指向它的链接?

            您可以使用文件夹名称发送某种 HTTP 请求,然后使用图像数据构建一个 json。我在我的应用程序中使用 Volley 库来处理 HTTP 请求,非常简单且运行良好

            【讨论】:

            • 是的,我也使用 Volley,但是如何生成 JSON 以及那个 blob 类型是什么?
            • 你在服务器端使用什么? php?红宝石? Blob 是一种数据库类型的数据,可用于存储图像
            • 我现在没有使用任何东西。不熟悉这些条款。
            【解决方案11】:

            对不起我的英语,您可以在创建文件夹时在数据库中添加文件夹名称,并在应用程序中加载所有文件夹名称,还可以将图像名称保存在数据库中,文件夹名称表初级键作为外键,当用户选择文件夹名称时使用该文件夹命名primery key并使用该键获取所有图像并将其加载到应用程序中。

            【讨论】:

            • 任何链接或教程?
            猜你喜欢
            • 1970-01-01
            • 2015-09-18
            • 2015-11-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-09-10
            • 2012-09-22
            相关资源
            最近更新 更多