上传带有进度条的大文件,Android中没有OutOfMemory错误 [英] Upload large file with progress bar and without OutOfMemory Error in Android

查看:212
本文介绍了上传带有进度条的大文件,Android中没有OutOfMemory错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在上传大型视频文件的时候遇到了一些问题(高达150MB)

<1>当我使用这个代码 Link1 。我可以上传带有进度条的小文件,但由于我的文件很大,所以android会给我提供 OutOfMemory Error 。 b
$ b

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

解决方案

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

1。第一个解决方案 Link1 这个解决方案适用于像上传图片的小文件,最高可达15MB。但是我可以如果文件非常大,则不会从OutOfMemory错误中清除。第二种解决方案( Link2 )真的是一个很好的解决方案,并显示进度条我使用了一个自定义的MultipartEntity类。代码在这里:

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

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

public class CustomMultiPartEntity extends MultipartEntity

{

private final ProgressListener listener;
$ b $ public CustomMultiPartEntity(final ProgressListener listener)
{
super();
this.listener = listener;

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

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

$ b @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;私人长期转移
;

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

$ b $ 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);


$ b code
$ b

我的活动代码是

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

导入org.apache.http.HttpEntity;
导入org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
导入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;
导入org.apache.http.util.EntityUtils;

import com.example.fileupload.C​​ustomMultiPartEntity.ProgressListener;

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

public class MainActivity extends Activity实现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;
私人TextView电视;
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);


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

$ b @Override
保护无效onProgressUpdate(整数...进展){
pb.setProgress(progress [0]);

$ b @Override
保护字符串doInBackground(Void ... params){
return upload();


private String upload(){
String responseString =no;

文件sourceFile =新文件(文件名);
if(!sourceFile.isFile()){
returnnot a file;
}
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(urlString);


$ {
CustomMultiPartEntity entity = new CustomMultiPartEntity(new ProgressListener(){
$ b @Override
public void transferred(long num) {
publishProgress((int)((num /(float)totalSize)* 100));
}
});

entity.addPart(type,new StringBody(video));
entity.addPart(uploadedfile,新的FileBody(sourceFile));
totalSize = entity.getContentLength();
httppost.setEntity(entity);
HttpResponse响应= httpclient.execute(httppost);
HttpEntity r_entity = response.getEntity();
responseString = EntityUtils.toString(r_entity);
$ b $ 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);
}


$ b @Override
public void onClick(View v){
// TODO自动生成的方法存根
new Uploadtask()。execute();
}

}


I am having some problem while uploading large video file(upto 150MB)

1.When I use this code Link1 .I able to upload small file with progress bar ,but as my file is large so android give me OutOfMemory Error.

2.If I use this code Link2. i am able to upload large file(this is really a good solution) but don't know how to show progess(like 20% complete or 80% complete and so on).so Please guide me.

解决方案

Finally I got solution of my question I want to share it ...

1.First solution Link1 This solution is ok with small files like image upload upto 15MB .But I could not get rid from OutOfMemory error if file is very large.

2.Second solution(Link2) is really a good solution and for showing progress bar I used a custom MultipartEntity class. Code is here:

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

And my activity code is

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

}

这篇关于上传带有进度条的大文件,Android中没有OutOfMemory错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆