admin管理员组

文章数量:819701

多线程下载视频

一个自定义箭头的网址

.htm  在加速的时候跳转 public void speed(){
        ++currentSpeed;
        if (currentSpeed>=10){
            currentSpeed=10;
            Toast.makeText(getContext(),"我比闪电还快",Toast.LENGTH_SHORT).show();
            Intent in=new Intent(getContext(),Main2Activity.class);
            getContext().startActivity(in);
        }
    }


public class content {

    public static final String MAIN = "/";
    public static final String zk = "iYXEPGn4e9c6dafce6e5cdd23287d2bb136ee7e9194d3e9?uri=vedio";


}


package com.example.zk3.api;
import com.example.zk3.bean.ZKbean;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Streaming;
import rx.Observable;
public interface HomeAPT {
    //首页
    @GET(content.zk)
    Observable<ZKbean> getvp();
    @Streaming
    @POST("{fileName}")
    Call<ResponseBody> downloadFile(@Path("fileName") String fileName, @Header("Range") String range);
    @Streaming
    @POST("{fileName}")
    Call<ResponseBody> getFileLength(@Path("fileName") String fileName);
    Retrofit RETROFIT=new Retrofit.Builder()
            .baseUrl(content.MAIN)
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    HomeAPT RETRO_API=RETROFIT.create(HomeAPT.class);
}

view层

package com.example.zk3.view;
import com.example.zk3.bean.ZKbean;

public interface IZKview {
    public void showvp(ZKbean zKbean);
}

model层

package com.example.zk3.model;


import com.example.zk3.bean.ZKbean;
public interface IZkmodel {
    public void showvp(VP vp);
    interface VP{
        public void shvp(ZKbean zKbean);
    }
}


package com.example.zk3.model;


import com.example.zk3.api.HomeAPT;
import com.example.zk3.bean.ZKbean;


import rx.Observer;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;


public class Zkmodel implements IZkmodel{
    @Override
    public void showvp(final VP vp) {
        HomeAPT.RETRO_API.getvp()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<ZKbean>() {
                    @Override
                    public void onCompleted() {


                    }


                    @Override
                    public void onError(Throwable e) {


                    }


                    @Override
                    public void onNext(ZKbean zKbean) {
                     vp.shvp(zKbean);
                    }
                });
    }
}


presenter层

package com.example.zk3.presenter;


import com.example.zk3.bean.ZKbean;
import com.example.zk3.model.IZkmodel;
import com.example.zk3.model.Zkmodel;
import com.example.zk3.view.IZKview;


import java.lang.ref.SoftReference;




public class VPpresenter implements IPresentetr<IZKview> {
    IZKview view;
    IZkmodel model;
    SoftReference<IZKview>ss;


    public VPpresenter(IZKview view) {
        attch(view);
        model=new Zkmodel();
    }
   public  void showViewpage(){
       model.showvp(new IZkmodel.VP() {
           @Override
           public void shvp(ZKbean zKbean) {
               ss.get().showvp(zKbean);
           }
       });
   }
    @Override
    public void attch(IZKview view) {
        ss=new SoftReference<IZKview>(view);
    }


    @Override
    public void detch() {
        ss.clear();


    }
}


main

package com.example.zk3;


import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;


import com.example.zk3.adapter.Readapter;
import com.example.zk3.bean.ZKbean;
import com.example.zk3.model.ImageApp;
import com.example.zk3.presenter.VPpresenter;
import com.example.zk3.view.IZKview;
import com.youth.banner.Banner;


import java.util.ArrayList;
import java.util.List;


import butterknife.BindView;
import butterknife.ButterKnife;


public class Main2Activity extends Baeactivity<VPpresenter> implements IZKview {


    @BindView(R.id.vp)
    Banner vp;
    @BindView(R.id.rv)
    RecyclerView rv;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        ButterKnife.bind(this);
        presenter.showViewpage();
    }


    @Override
    public void createpresenter() {
        presenter = new VPpresenter(this);


    }


    @Override
    public void showvp(final ZKbean zKbean) {
        List<String> list_vp = new ArrayList<>();
        for (int i = 0; i < zKbean.getData().size(); i++) {
            list_vp.add(zKbean.getData().get(i).getImage_url());
        }
        vp.setImageLoader(new ImageApp());
        vp.setImages(list_vp);
        vp.start();




        LinearLayoutManager mar=new LinearLayoutManager(this);
        rv.setLayoutManager(mar);
        Readapter adapter = new Readapter(Main2Activity.this, zKbean);
        rv.setAdapter(adapter);
       adapter.setOnItemClickListener(new Readapter.OnItemClickListener() {
           @Override
           public void onItemClick(int position, String vediourl) {
               Intent intent=new Intent(Main2Activity.this,MovreActivity.class);
               intent.putExtra("url",vediourl);
               startActivity(intent);
           }
       });


    }
}

main

package com.example.zk3;


import android.annotation.SuppressLint;
import android.content.Intent;
import android.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;


import com.example.zk3.FileDownloadThread;


import java.io.File;
import java.io.IOException;
import java.MalformedURLException;
import java.URL;
import java.URLConnection;


import butterknife.BindView;
import butterknife.ButterKnife;


public class MovreActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = MovreActivity.class.getSimpleName();
    @BindView(R.id.vv)
    VideoView vv;
    @BindView(R.id.download_btn)
    Button downloadBtn;
    @BindView(R.id.download_progress)
    ProgressBar downloadProgress;
    @BindView(R.id.download_message)
    TextView downloadMessage;
    String p;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_movre);
        ButterKnife.bind(this);
        Intent intent = getIntent();
         p = intent.getStringExtra("url");


        downloadBtn.setOnClickListener(this);
    }


    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.download_btn) {
            doDownload();
        }
    }


    /**
     * 使用Handler更新UI界面信息
     */
    @SuppressLint("HandlerLeak")
    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {


            downloadProgress.setProgress(msg.getData().getInt("size"));


            float temp = (float) downloadProgress.getProgress()
                    / (float) downloadProgress.getMax();


            int progress = (int) (temp * 100);
            if (progress == 100) {
                Toast.makeText(MovreActivity.this, "下载完成!", Toast.LENGTH_LONG).show();
                MediaController media= new MediaController(MovreActivity.this);
                Uri uri = Uri.parse(p);
                vv.setVideoURI(uri);
                vv.setMediaController(media);
                vv.start();








            }
            downloadMessage.setText("下载进度:" + progress + " %");


        }
    };




    private void doDownload() {
        // 获取SD卡路径
        String path = Environment.getExternalStorageDirectory()
                + "/amosdownload/";
        File file = new File(path);
        // 如果SD卡目录不存在创建
        if (!file.exists()) {
            file.mkdir();
        }
        // 设置progressBar初始化
        downloadProgress.setProgress(0);


        // 简单起见,我先把URL和文件名称写死,其实这些都可以通过HttpHeader获取到
        String downloadUrl = p;
        String fileName = "shipin.mp4";
        int threadNum = 5;
        String filepath = path + fileName;
        Log.d(TAG, "download file  path:" + filepath);
        downloadTask task = new downloadTask(downloadUrl, threadNum, filepath);
        task.start();
    }
    /**
     * 多线程文件下载
     *
     * @author yangxiaolong
     * @2014-8-7
     */
    class downloadTask extends Thread {
        private String downloadUrl;// 下载链接地址
        private int threadNum;// 开启的线程数
        private String filePath;// 保存文件路径地址
        private int blockSize;// 每一个线程的下载量


        public downloadTask(String downloadUrl, int threadNum, String fileptah) {
            this.downloadUrl = downloadUrl;
            this.threadNum = threadNum;
            this.filePath = fileptah;
        }


        @Override
        public void run() {


            FileDownloadThread[] threads = new FileDownloadThread[threadNum];
            try {
                URL url = new URL(downloadUrl);
                Log.d(TAG, "download file http path:" + downloadUrl);
                URLConnection conn = url.openConnection();
                // 读取下载文件总大小
                int fileSize = conn.getContentLength();
                if (fileSize <= 0) {
                    System.out.println("读取文件失败");
                    return;
                }
                // 设置ProgressBar最大的长度为文件Size
                downloadProgress.setMax(fileSize);


                // 计算每条线程下载的数据长度
                blockSize = (fileSize % threadNum) == 0 ? fileSize / threadNum
                        : fileSize / threadNum + 1;


                Log.d(TAG, "fileSize:" + fileSize + "  blockSize:" + blockSize);


                File file = new File(filePath);
                for (int i = 0; i < threads.length; i++) {
                    // 启动线程,分别下载每个线程需要下载的部分
                    threads[i] = new FileDownloadThread(url, file, blockSize,
                            (i + 1));
                    threads[i].setName("Thread:" + i);
                    threads[i].start();
                }


                boolean isfinished = false;
                int downloadedAllSize = 0;
                while (!isfinished) {
                    isfinished = true;
                    // 当前所有线程下载总量
                    downloadedAllSize = 0;
                    for (int i = 0; i < threads.length; i++) {
                        downloadedAllSize += threads[i].getDownloadLength();
                        if (!threads[i].isCompleted()) {
                            isfinished = false;
                        }
                    }
                    // 通知handler去更新视图组件
                    Message msg = new Message();
                    msg.getData().putInt("size", downloadedAllSize);
                    mHandler.sendMessage(msg);
                    // Log.d(TAG, "current downloadSize:" + downloadedAllSize);
                    Thread.sleep(1000);// 休息1秒后再读取下载进度
                }
                Log.d(TAG, " all of downloadSize:" + downloadedAllSize);


            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


        }
    }
}
net包

package com.example.zk3;


import android.util.Log;


import com.example.zk3.api.HomeAPT;
import com.example.zk3.utils.DialogUtils;
import com.example.zk3.utils.RetrofitManager;


import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;


import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;




public class DownloadThread extends Thread {
    private String downloadUrl="";
    private String path;
    private int threadNum=5;


    public DownloadThread(String downloadUrl, String path) {
        this.downloadUrl = downloadUrl;
        this.path = path;
    }


    @Override
    public void run() {
        OkHttpClient client=new OkHttpClient.Builder().build();


        HomeAPT setcreate = RetrofitManager.getinstantce("", client).setcreate(HomeAPT.class);
        setcreate.getFileLength(downloadUrl).enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                String length=response.headers().get("Content-Length");
                downloadTask(Long.valueOf(length));
            }


            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {


            }
        });
    }
    public void downloadTask(long length){
        final File file=new File(path);
        if(!file.exists()){
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        DialogUtils.MAX_SIZE=length;
        long blockSize=length/threadNum;
        for (int i = 0; i < threadNum; i++) {
            final long startPosition=blockSize*i;
            if(i==threadNum-1){
                blockSize=length-blockSize*(threadNum-1);
            }
            String range="bytes="+startPosition+"-"+(startPosition+blockSize-1);
            OkHttpClient client=new OkHttpClient.Builder().build();


            HomeAPT setcreate = RetrofitManager.getinstantce("", client).setcreate(HomeAPT.class);
            setcreate.downloadFile(downloadUrl,range).enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                    if(response.isSuccess()){
                        try {
                            BufferedInputStream bis=new BufferedInputStream(response.body().byteStream());
                            RandomAccessFile raf=new RandomAccessFile(file,"rwd");
                            raf.seek(startPosition);
                            byte[] buff=new byte[1024*8];
                            int len=0;
                            while ((len=bis.read(buff))!=-1){
                                raf.write(buff,0,len);
                                DialogUtils.PROGRESS+=len;
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }


                    }else{
                        Log.i("=====onResponse=====", "onResponse: " + "失败");
                    }
                }


                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {


                }
            });
        }
    }
}


package com.example.zk3;


import android.util.Log;


import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.URL;
import java.URLConnection;


/**
 * 文件下载类
 *
 * @
 * @2014-5-6
 */
public class FileDownloadThread extends Thread {


private static final String TAG = FileDownloadThread.class.getSimpleName();


/** 当前下载是否完成 */
private boolean isCompleted = false;
/** 当前下载文件长度 */
private int downloadLength = 0;
/** 文件保存路径 */
private File file;
/** 文件下载路径 */
private URL downloadUrl;
/** 当前下载线程ID */
private int threadId;
/** 线程下载数据长度 */
private int blockSize;


/**
*
* @param url:文件下载地址
* @param file:文件保存路径
* @param blocksize:下载数据长度
* @param threadId:线程ID
*/
public FileDownloadThread(URL downloadUrl, File file, int blocksize,
 int threadId) {
this.downloadUrl = downloadUrl;
this.file = file;
this.threadId = threadId;
this.blockSize = blocksize;
}


@Override
public void run() {


BufferedInputStream bis = null;
RandomAccessFile raf = null;


try {
URLConnection conn = downloadUrl.openConnection();
conn.setAllowUserInteraction(true);


int startPos = blockSize * (threadId - 1);//开始位置
int endPos = blockSize * threadId - 1;//结束位置


//设置当前线程下载的起点、终点
conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
System.out.println(Thread.currentThread().getName() + "  bytes="
+ startPos + "-" + endPos);


byte[] buffer = new byte[1024];
bis = new BufferedInputStream(conn.getInputStream());


raf = new RandomAccessFile(file, "rwd");
raf.seek(startPos);
int len;
while ((len = bis.read(buffer, 0, 1024)) != -1) {
raf.write(buffer, 0, len);
downloadLength += len;
}
isCompleted = true;
Log.d(TAG, "current thread task has finished,all size:"
+ downloadLength);


} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (raf != null) {
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


/**
* 线程文件是否下载完毕
*/
public boolean isCompleted() {
return isCompleted;
}


/**
* 线程下载文件长度
*/
public int getDownloadLength() {
return downloadLength;
}


}


utils

package com.example.zk3.utils;


import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.SystemClock;
import android.support.v7.app.AlertDialog;


import com.example.zk3.DownloadThread;




/**
 * Created by on 2017/11/9.
 */


public class DialogUtils {
    public static long MAX_SIZE = 0;
    public static long PROGRESS = -2;


    public static void showUpdataDialog(final Context context,final String shipUrl){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle("是否更新")
                .setMessage("太旧了,更新吧")
                .setNegativeButton("就不", null)
                .setPositiveButton("可以", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        new DownloadThread(shipUrl, context.getCacheDir() + "/.mp4").start();
//                        showProgress(context);
                    }
                }).show();
    }


    public static void showProgress(final Context context, String vediourl){
        final ProgressDialog pd = new ProgressDialog(context);
        pd.setTitle("正在更新");
        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        pd.setMax(100);
        pd.show();


        new AsyncTask<String, Integer, String>(){


            @Override
            protected String doInBackground(String... strings) {
                while (PROGRESS + 1 < MAX_SIZE){
                    SystemClock.sleep(100);
                    if(MAX_SIZE > 0){
                        publishProgress((int)(PROGRESS * 100 / MAX_SIZE));
                    }
                }
                return null;
            }


            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                pd.dismiss();
            }


            @Override
            protected void onProgressUpdate(Integer... values) {
                super.onProgressUpdate(values);
                pd.setProgress(values[0]);
            }
        }.execute();
    }
}


package com.example.zk3.utils;


import android.os.Handler;


import java.util.HashMap;


import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;




public class OkHttpUtils {
    public HashMap<String,Object> map=new HashMap<>();
    //实例一个在ui的handler
    private Handler handler=new Handler();
    public Handler getHandler(){
        return  handler;
    }
    //单例
    private static OkHttpUtils okHttpUtils=new OkHttpUtils();
    private OkHttpUtils(){};
    public static OkHttpUtils getInstance(){
        return okHttpUtils;
    }
    private OkHttpClient client;
    private void initOkhttpClient(){
        if(client==null){
            client=new OkHttpClient.Builder().build();
        }
    }
    //公用的get请求方法,完成的各功能不确定
    public void doGet(String url,Callback callback){
        initOkhttpClient();
        Request request=new Request.Builder().url(url).build();
        Call call=client.newCall(request);
        call.enqueue(callback);
    }
    public void doPost(String url,HashMap<String,String> map,Callback callback){
        initOkhttpClient();
        FormBody.Builder body=new FormBody.Builder();
        for (String key:map.keySet()) {
            body.add(key,map.get(key));
        }
        Request request=new Request.Builder().url(url).post(body.build()).build();
        Call call=client.newCall(request);
        call.enqueue(callback);
    }
}



package com.example.zk3.utils;


import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;


/**
 * 
 */


public class RetrofitManager {
   private String baseUrl;
    private Retrofit retrofit;
    OkHttpClient client;
    private  static RetrofitManager retrofitManager;
    private RetrofitManager(){}
    private RetrofitManager(String baseUrl, OkHttpClient client) {
        this.baseUrl = baseUrl;
        this.client = client;
        initRetrofit();
    }


    public static RetrofitManager getinstantce(String baseUrl, OkHttpClient client){
//        if(retrofitManager==null){
            retrofitManager=new RetrofitManager(baseUrl,client);
//        }
        return retrofitManager;
    }


    public void initRetrofit(){
        retrofit=new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(client)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    public <T> T setcreate(Class<T> regsServer){
        return retrofit.create(regsServer);
    }
}




package com.example.zk3.utils;


import android.os.Handler;


import java.io.IOException;


import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;


public abstract class OkUiCallback implements Callback {
    //给handler赋一个主线程的handler,然後这个handler的信息就可以拼接到主线程的handler里了
    private Handler handler=OkHttpUtils.getInstance().getHandler();
    //建两个方法,一个成功,一个失败,用于被子线程调用赋值
    public abstract void onFailed(Call call, IOException e);
    public abstract void onSuccess(String str)throws IOException;
    //数据请求失败
    @Override
    public void onFailure(final Call call,final IOException e) {
        //该方法就是把 线程post到handler所在的线程;
        handler.post(new Runnable() {
            @Override
            public void run() {
                onFailed(call,e);
            }
        });


    }
    //数据请求成功
    @Override
    public void onResponse(Call call, Response response) throws IOException {
       final String str=response.body().string();
        //该方法就是把 线程post到handler所在的线程;
        handler.post(new Runnable() {
            @Override
            public void run() {
                try {
                    onSuccess(str);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });


    }
}



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""
    xmlns:app=""
    xmlns:tools=""
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    tools:context="com.example.zk3.MovreActivity">
    <Button
        android:id="@+id/download_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="80dp"
        android:text="Download"
        android:visibility="visible" />


    <ProgressBar
        android:id="@+id/download_progress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:indeterminate="false"
        android:indeterminateOnly="false"
        android:maxHeight="20dp"
        android:minHeight="20dp"
        android:paddingLeft="8dp"
        android:paddingRight="8dp"
        android:progress="0"
        android:progressDrawable="@drawable/progressbar_horizontal_1"
        android:secondaryProgress="0" />


    <TextView
        android:id="@+id/download_message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal|center_vertical"
        android:text="下载进度:0%" />


<VideoView
    android:id="@+id/vv"
    android:layout_width="match_parent"
    android:layout_height="400dp"
    android:layout_below="@+id/download_message"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />
</LinearLayout>

本文标签: 多线程下载视频