在 Android 中上传带有进度条且没有 OutOfMemory 错误的大文件

2023-11-22

我在上传大型视频文件(最大 150MB)时遇到问题

1.当我使用此代码时Link1.我可以上传带有进度条的小文件,但是由于我的文件很大,所以android给了我内存不足错误.

2.如果我使用这个代码Link2。我能够上传大文件(这确实是一个很好的解决方案),但不知道如何显示进度(例如完成 20% 或完成 80% 等等)。所以请指导我。


最后我得到了我想分享的问题的解决方案......

1.第一种解决方案Link1这个解决方案对于像上传高达 15MB 的图像这样的小文件来说是可以的。但是如果文件非常大,我无法摆脱 OutOfMemory 错误。

2.第二种解决方案(Link2)确实是一个很好的解决方案,为了显示进度条,我使用了自定义的 MultipartEntity 类。代码在这里:

    import java.io.FilterOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.nio.charset.Charset;

    import org.apache.http.entity.mime.HttpMultipartMode;
    import org.apache.http.entity.mime.MultipartEntity;

    public class CustomMultiPartEntity extends MultipartEntity

{

    private final ProgressListener listener;

    public CustomMultiPartEntity(final ProgressListener listener)
    {
        super();
        this.listener = listener;
    }

    public CustomMultiPartEntity(final HttpMultipartMode mode, final ProgressListener listener)
    {
        super(mode);
        this.listener = listener;
    }

    public CustomMultiPartEntity(HttpMultipartMode mode, final String boundary, final Charset charset, final ProgressListener listener)
    {
        super(mode, boundary, charset);
        this.listener = listener;
    }

    @Override
    public void writeTo(final OutputStream outstream) throws IOException
    {
        super.writeTo(new CountingOutputStream(outstream, this.listener));
    }

    public static interface ProgressListener
    {
        void transferred(long num);
    }

    public static class CountingOutputStream extends FilterOutputStream
    {

        private final ProgressListener listener;
        private long transferred;

        public CountingOutputStream(final OutputStream out, final ProgressListener listener)
        {
            super(out);
            this.listener = listener;
            this.transferred = 0;
        }

        public void write(byte[] b, int off, int len) throws IOException
        {
            out.write(b, off, len);
            this.transferred += len;
            this.listener.transferred(this.transferred);
        }

        public void write(int b) throws IOException
        {
            out.write(b);
            this.transferred++;
            this.listener.transferred(this.transferred);
        }
    }
}

我的活动代码是

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import com.example.fileupload.CustomMultiPartEntity.ProgressListener;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {
    private ProgressBar pb;
    private final String filename = "/mnt/sdcard/vid.mp4";
    // private final String filename = "/mnt/sdcard/a.3gp";
    private String urlString = "http://10.0.2.2:8080/FileUploadServlet1/UploadServlet";
    private TextView tv;
    long totalSize = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.textView1);
        findViewById(R.id.button1).setOnClickListener(this);
        tv.setText("init");
        pb = (ProgressBar) findViewById(R.id.progressBar1);

    }

    private class Uploadtask extends AsyncTask<Void, Integer, String> {
        @Override
        protected void onPreExecute() {
            pb.setProgress(0);
            tv.setText("shuru");
            super.onPreExecute();
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            pb.setProgress(progress[0]);
        }

        @Override
        protected String doInBackground(Void... params) {
            return upload();
        }

        private String upload() {
            String responseString = "no";

            File sourceFile = new File(filename);
            if (!sourceFile.isFile()) {
                return "not a file";
            }
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(urlString);


            try {
                CustomMultiPartEntity entity=new CustomMultiPartEntity(new ProgressListener() {

                    @Override
                    public void transferred(long num) {
                        publishProgress((int) ((num / (float) totalSize) * 100));                       
                    }
                });

                entity.addPart("type", new StringBody("video"));
                entity.addPart("uploadedfile", new FileBody(sourceFile));
                totalSize = entity.getContentLength();
                httppost.setEntity(entity);
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity r_entity = response.getEntity();
                responseString = EntityUtils.toString(r_entity);

            } catch (ClientProtocolException e) {
                responseString = e.toString();
            } catch (IOException e) {
                responseString = e.toString();
            }

            return responseString;

        }


        @Override
        protected void onPostExecute(String result) {
            tv.setText(result);
            super.onPostExecute(result);
        }

    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        new Uploadtask().execute();
    }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Android 中上传带有进度条且没有 OutOfMemory 错误的大文件 的相关文章

随机推荐

  • Maven 插件在构建过程中执行多次

    我有一个具有多个重叠配置文件的 Maven 项目 我想在每次构建开始时显示活动配置文件 所以我将以下内容放入pom xml
  • CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触摸视图

    我在 Android 中遇到以下错误 CalledFromWrongThreadException 仅 创建的原始线程 视图层次结构可以触摸其视图 当我尝试更新 Activity 中的 Textview 时 似乎会发生这种情况 更新 Tex
  • ResultSet getFetchSize() 似乎不起作用?

    我遇到了问题getFetchSize 功能 我只需要知道 SQL 查询是否返回零行 我尝试过这个简单的声明 if rs getFetchSize 0 System out println HEADLINE where rs是属于Result
  • 动态添加和删除表行 - Android

    我正在尝试从 TableLayout 中动态添加和删除行 布局在 xml 文件中定义 我能够成功删除一行 但是当我调用相应的 addView 命令时什么也没有发生 table TableLayout findViewById R id ta
  • 将 MySql 日期时间戳转换为 JavaScript 日期格式

    有谁知道我如何获取MySQLdatetime数据类型值 例如YYYY MM DD HH MM SS并解析它或将其转换为在 JavaScript 中工作Date 函数 例如 Date YYYY MM DD HH MM SS 谢谢你 这里给出的
  • php - ftp_get - 警告:ftp_get():打开 BINARY 模式数据连接

    我正在尝试编写一个从 FTP 服务器下载文件的脚本 它们都相当大 每个接近 2GB 该脚本开始运行 但最终因上述错误而终止 与大小有关吗 有没有解决的办法 这是代码
  • Docker RUN 不会保留文件

    我有一个 Docker 问题 它不持久通过 RUN 启动命令 这是我的 Dockerfile FROM jenkins latest RUN echo foo gt var jenkins home toto ls alh var jenk
  • Tomcat NioEndpoint - 运行套接字处理器时出错

    在Spring Boot生产应用中 偶尔会抛出以下异常 o a t u n NioEndpoint Error running socket processor java util NoSuchElementException No val
  • 如何为重叠的 x 轴标签替换新行?

    当在 x 轴上绘制长文本因子时 ggplot 的效果并不好 我想换一条新线 以便更清晰 因此下图中的红色标记标签应该向下一行 我在 中找到了这个问题的答案在这里评论但无法工作 代码是 scale x discrete labels func
  • 在Java中实现阻塞函数调用

    在 Java 中实现阻塞函数调用的推荐 最佳方法是什么 稍后可以通过另一个线程的调用来解除阻塞 基本上我想在一个对象上有两个方法 其中第一个调用会阻塞任何调用线程 直到另一个线程运行第二个方法 public class Blocker An
  • javascript 的 Promise、事件循环和作业队列

    考虑以下代码 function foo console log foo new Promise function resolve reject setTimeout function resolve RESOLVING 5000 then
  • OSMdroid 添加自定义图标到 ItemizedOverlay

    我正在使用 ItemizedIconOverlay 类 当前正在地图上显示事件以及具有相同默认图标的用户位置 如何更改每个叠加层的图标集 是否有类似于 google maps 示例的内容 drawable getResources getD
  • Keras:类型错误:无法使用 KerasClassifier pickle _thread.lock 对象

    import pandas as pd import numpy as np import matplotlib pyplot as plt dataset pd read csv Churn Modelling csv X dataset
  • 在选择框中重新填充日期

    我在 Rails 中创建了一个 date select 它有 3 个选择框 一个代表年份 一个代表月份 一个代表日期 2 月 31 日在他们身上是相当令人困惑的 我希望能够只让选择框包含有效日期 我的意思是 当您选择二月时 31 日 30
  • 重建/获取 PHP 函数的源代码

    我可以通过编程方式通过函数名称获取函数的源代码吗 Like function blah a b return a b echo getFunctionCode blah 是否可以 是否有任何 php 自描述函数可以重构函数 类代码 我的意思
  • 如何禁用 Android Studio 3.0 的即时运行

    进行一些更改后 我收到错误 会话 app 安装 APK 时出错 据一些人说 这是因为 Instant Run 在最新的Stable Android Studio 3 0上 在构建 执行 部署我没有任何 即时运行 选项 即使在设置搜索中进行了
  • 如何在C++中将自定义项目添加到系统菜单?

    我需要枚举所有正在运行的应用程序 特别是所有顶部窗户 对于每个窗口 我需要将自定义项目添加到该窗口的系统菜单中 我怎样才能在 C 中实现这一点 Update 我非常乐意为 Windows MacOS 和 Ubuntu 提供解决方案 不过 我
  • 使用钉枪加快 Clojure 启动时间

    我时不时地想用一下会很好clojure for 外壳脚本 但是大约 900ms 的启动时间太慢了 然后我会google首页对于 nailgun clojure 但显示的唯一结果是针对像 vimclojure 这样的特殊情况 那时我假装没有时
  • 从python中的字节中提取LSB位

    我在变量 DATA 中有一个字节 我想从中提取 LSB 位并打印它 我对 python 很陌生 我发现很多文章都有复杂的按位加法逻辑 而且所有这些都很难理解 我正在寻找一个简单的逻辑 就像我们对字符串所做的那样 例如 DATA 7 1 请帮
  • 在 Android 中上传带有进度条且没有 OutOfMemory 错误的大文件

    我在上传大型视频文件 最大 150MB 时遇到问题 1 当我使用此代码时Link1 我可以上传带有进度条的小文件 但是由于我的文件很大 所以android给了我内存不足错误 2 如果我使用这个代码Link2 我能够上传大文件 这确实是一个很