依赖
compile 'org.greenrobot:greendao:3.2.0'
compile 'com.youth.banner:banner:1.4.9'
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.squareup.okio:okio:1.13.0'
compile 'com.facebook.fresco:fresco:0.11.0'
compile 'org.greenrobot:greendao:3.2.0'
compile 'io.reactivex:rxjava:1.0.14'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
compile 'io.reactivex:rxandroid:1.0.1'
compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
代码部分
适配器
public class ShowAdapter extends RecyclerView.Adapter<ShowAdapter.MyViewHolder> implements View.OnClickListener{
private Context context;
private List<Beans.DataBean> chalist;
//利用接口回调实现点击事件
//再实例,然后创建方法
private OnItemClickListener mOnItemClickListener = null;
//点击事件
@Override
public void onClick(View view) {
if (mOnItemClickListener!=null){
mOnItemClickListener.onItemClick(view, (Integer) view.getTag());
}
}
public static interface OnItemClickListener {
void onItemClick(View view, int position);
}
public ShowAdapter(Context context, List<Beans.DataBean> chalist) {
this.context = context;
this.chalist = chalist;
Log.i("33333", "onBindViewHolder: "+chalist.size());
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=View.inflate(context, R.layout.rcy_item_line,null);
MyViewHolder holder=new MyViewHolder(view);
//调用点击
view.setOnClickListener(this);
return holder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.tv.setText(chalist.get(position).getContent());
// String[] split = sousuolist.get(position).getImages().split("\\|");
// DraweeController ff= Fresco.newDraweeControllerBuilder()
// .setUri(String.valueOf(split[0]))
// .setAutoPlayAnimations(true)
// .build();
// holder.iv.setController(ff);
// String s =chalist.get(position).getList().get(0).getImages().split("\\|")[0];
DraweeController ff= Fresco.newDraweeControllerBuilder()
.setUri(chalist.get(position).getImage_url())
.setAutoPlayAnimations(true)
.build();
holder.iv.setController(ff);
//把条目的下标position设置给holder
holder.itemView.setTag(position);
//ImageLoader.getInstance().displayImage(list.get(position).getList().get(0).getImages(),holder.iv);
//点击条目删除
// holder.itemView.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// chalist.remove(position);
// notifyItemRemoved(position);
// }
// });
}
public void setmOnItemClickListener(OnItemClickListener listener){
this.mOnItemClickListener=listener;
}
@Override
public int getItemCount() {
return chalist.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
public TextView tv;
public SimpleDraweeView iv;
public MyViewHolder(View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.tv);
iv = itemView.findViewById(R.id.img);
}
}
}
加载图片
public class Img extends ImageLoader {
@Override
public void displayImage(Context context, Object path, ImageView imageView) {
Glide.with(context)
.load(path)
.into(imageView);
}
}
VIEW层
public interface Iview {
void setData(List<Beans.DataBean> beanList);
//首页小分类
//void setFL(List<Frag_FL_Bean.DataBean> fenlei);
}
MODEL层
public interface IModel {
void setObSerVer(Observer obSerVer);
//void fenlei(Observer FLobserver);
}
public class MyModel implements IModel{
@Override
public void setObSerVer(Observer obSerVer) {
OkHttpClient okclient = new OkHttpClient.Builder().build();
RetrofitManager.getInstance(RequestApi.BASE_URL,okclient)
.setCreate(RequestApi.class)
.getData()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(obSerVer);
// Retrofit retrofit=new Retrofit.Builder()
// .client(okclient)
// .baseUrl(Constant.BASE_URL)
// .addConverterFactory(GsonConverterFactory.create())
// .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
// .build();
// URLUtils urlUtils = retrofit.create(URLUtils.class);
// urlUtils.getObservable()
// .subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
// .subscribe(obSerVer);
}
}
PRESENTER层
public class MyPresenter {
IModel model;
Iview view;
public MyPresenter(Iview view) {
this.view = view;
model=new MyModel();
}
public void loadData(){
model.setObSerVer(new Observer<Beans>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Log.i("///", "onError: "+e);
}
@Override
public void onNext(Beans beans ) {
List<Beans.DataBean> data = beans.getData();
Log.i("/", "onNext: "+data.size());
view.setData(data);
}
});
}
}
1.
public interface RequestApi {
public static final String BASE_URL = "http://result.eolinker.com/";
@GET("iYXEPGn4e9c6dafce6e5cdd23287d2bb136ee7e9194d3e9?uri=vedio")
Observable<Beans> getData();
// @Streaming
// @POST("{fileName}")
// Call<ResponseBody> downloadFile(@Path("fileName") String fileName, @Header("Range") String range);
//
// @Streaming
// @POST("{fileName}")
// Call<ResponseBody> getFileLenght(@Path("fileName") String fileName);
}
2.
public class RetrofitManager {
private Retrofit mRetrofit;
private String baseUrl;
OkHttpClient client;
private static RetrofitManager mRetrofitManager;
private RetrofitManager(String baseUrl,OkHttpClient client){
this.baseUrl=baseUrl;
this.client=client;
initRetrofit();
}
public static synchronized RetrofitManager getInstance(String baseUrl,OkHttpClient client){
if (mRetrofitManager == null){
mRetrofitManager = new RetrofitManager(baseUrl,client);
}
return mRetrofitManager;
}
private void initRetrofit() {
mRetrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(client)
.build();
}
public <T> T setCreate(Class<T> reqServer){
return mRetrofit.create(reqServer);
}
}
3.
public class Api {
public static final String BanUrl="http://result.eolinker.com/iYXEPGn4e9c6dafce6e5cdd23287d2bb136ee7e9194d3e9?uri=vedio";
}
4.
public class App extends Application {
public static UserDao userDao;
@Override
public void onCreate() {
super.onCreate();
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(this, "lenvess.db", null);
DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDb());
DaoSession daoSession = daoMaster.newSession();
userDao = daoSession.getUserDao();
}
}
5.
public class DownlaodSqlTool {
/**
* 创建下载的具体信息
*/
public void insertInfos(List<DownloadInfo> infos) {
for (DownloadInfo info : infos) {
User user = new User(null, info.getThreadId(), info.getStartPos(), info.getEndPos(), info.getCompeleteSize(), info.getUrl());
userDao.insert(user);
}
}
/**
* 得到下载具体信息
*/
public List<DownloadInfo> getInfos(String urlstr) {
List<DownloadInfo> list = new ArrayList<DownloadInfo>();
List<User> list1 = userDao.queryBuilder().where(UserDao.Properties.Url.eq(urlstr)).build().list();
for (User user : list1) {
DownloadInfo infoss = new DownloadInfo(
user.getThread_id(), user.getStart_pos(), user.getEnd_pos(),
user.getCompelete_size(), user.getUrl());
Log.d("main-----", infoss.toString());
list.add(infoss);
}
return list;
}
/**
* 更新数据库中的下载信息
*/
public void updataInfos(int threadId, int compeleteSize, String urlstr) {
User user = userDao.queryBuilder()
.where(UserDao.Properties.Thread_id.eq(threadId), UserDao.Properties.Url.eq(urlstr)).build().unique();
user.setCompelete_size(compeleteSize);
userDao.update(user);
}
/**
* 下载完成后删除数据库中的数据
*/
public void delete(String url) {
userDao.deleteAll();
}
}
6.
public class DownloadHttpTool {
/**
* 利用Http协议进行多线程下载具体实践类
*/
private static final String TAG = DownloadHttpTool.class.getSimpleName();
private int threadCount;//线程数量
private String urlstr;//URL地址
private Context mContext;
private Handler mHandler;
private List<DownloadInfo> downloadInfos;//保存下载信息的类
private String localPath;//目录
private String fileName;//文件名
private int fileSize;
private DownlaodSqlTool sqlTool;//文件信息保存的数据库操作类
private enum Download_State {
Downloading, Pause, Ready;//利用枚举表示下载的三种状态
}
private Download_State state = Download_State.Ready;//当前下载状态
private int globalCompelete = 0;//所有线程下载的总数
public DownloadHttpTool(int threadCount, String urlString,
String localPath, String fileName, Context context, Handler handler) {
super();
this.threadCount = threadCount;
this.urlstr = urlString;
this.localPath = localPath;
this.mContext = context;
this.mHandler = handler;
this.fileName = fileName;
sqlTool = new DownlaodSqlTool();
}
//在开始下载之前需要调用ready方法进行配置
public void ready() {
Log.w(TAG, "ready");
globalCompelete = 0;
downloadInfos = sqlTool.getInfos(urlstr);
if (downloadInfos.size() == 0) {
initFirst();
} else {
File file = new File(localPath + "/" + fileName);
if (!file.exists()) {
sqlTool.delete(urlstr);
initFirst();
} else {
fileSize = downloadInfos.get(downloadInfos.size() - 1)
.getEndPos();
for (DownloadInfo info : downloadInfos) {
globalCompelete += info.getCompeleteSize();
}
Log.w(TAG, "globalCompelete:::" + globalCompelete);
}
}
}
public void start() {
Log.w(TAG, "start");
if (downloadInfos != null) {
if (state == Download_State.Downloading) {
return;
}
state = Download_State.Downloading;
for (DownloadInfo info : downloadInfos) {
Log.v(TAG, "startThread");
new DownloadThread(info.getThreadId(), info.getStartPos(),
info.getEndPos(), info.getCompeleteSize(),
info.getUrl()).start();
}
}
}
public void pause() {
state = Download_State.Pause;
}
public void delete() {
compelete();
File file = new File(localPath + "/" + fileName);
file.delete();
}
public void compelete() {
sqlTool.delete(urlstr);
}
public int getFileSize() {
return fileSize;
}
public int getCompeleteSize() {
return globalCompelete;
}
//第一次下载初始化
private void initFirst() {
Log.w(TAG, "initFirst");
try {
URL url = new URL(urlstr);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
fileSize = connection.getContentLength();
Log.w(TAG, "fileSize::" + fileSize);
File fileParent = new File(localPath);
if (!fileParent.exists()) {
fileParent.mkdir();
}
File file = new File(fileParent, fileName);
if (!file.exists()) {
file.createNewFile();
}
// 本地访问文件
RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
accessFile.setLength(fileSize);
accessFile.close();
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
int range = fileSize / threadCount;
downloadInfos = new ArrayList<DownloadInfo>();
for (int i = 0; i < threadCount - 1; i++) {
DownloadInfo info = new DownloadInfo(i, i * range, (i + 1) * range
- 1, 0, urlstr);
downloadInfos.add(info);
}
DownloadInfo info = new DownloadInfo(threadCount - 1, (threadCount - 1)
* range, fileSize - 1, 0, urlstr);
downloadInfos.add(info);
sqlTool.insertInfos(downloadInfos);
}
//自定义下载线程
private class DownloadThread extends Thread {
private int threadId;
private int startPos;
private int endPos;
private int compeleteSize;
private String urlstr;
private int totalThreadSize;
public DownloadThread(int threadId, int startPos, int endPos,
int compeleteSize, String urlstr) {
this.threadId = threadId;
this.startPos = startPos;
this.endPos = endPos;
totalThreadSize = endPos - startPos + 1;
this.urlstr = urlstr;
this.compeleteSize = compeleteSize;
}
@Override
public void run() {
HttpURLConnection connection = null;
RandomAccessFile randomAccessFile = null;
InputStream is = null;
try {
randomAccessFile = new RandomAccessFile(localPath + "/"
+ fileName, "rwd");
randomAccessFile.seek(startPos + compeleteSize);
URL url = new URL(urlstr);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
connection.setRequestProperty("Range", "bytes="
+ (startPos + compeleteSize) + "-" + endPos);
is = connection.getInputStream();
byte[] buffer = new byte[1024];
int length = -1;
while ((length = is.read(buffer)) != -1) {
randomAccessFile.write(buffer, 0, length);
compeleteSize += length;
Message message = Message.obtain();
message.what = threadId;
message.obj = urlstr;
message.arg1 = length;
mHandler.sendMessage(message);
sqlTool.updataInfos(threadId, compeleteSize, urlstr);
Log.w(TAG, "Threadid::" + threadId + " compelete::"
+ compeleteSize + " total::" + totalThreadSize);
if (compeleteSize >= totalThreadSize) {
break;
}
if (state != Download_State.Downloading) {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
randomAccessFile.close();
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
7.
public class DownloadInfo {
/**
* 保存每个下载线程下载信息类
*
*/
private int threadId;// 下载器id
private int startPos;// 开始点
private int endPos;// 结束点
private int compeleteSize;// 完成度
private String url;// 下载文件的URL地址
public DownloadInfo(int threadId, int startPos, int endPos,
int compeleteSize, String url) {
this.threadId = threadId;
this.startPos = startPos;
this.endPos = endPos;
this.compeleteSize = compeleteSize;
this.url = url;
}
public DownloadInfo() {
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getThreadId() {
return threadId;
}
public void setThreadId(int threadId) {
this.threadId = threadId;
}
public int getStartPos() {
return startPos;
}
public void setStartPos(int startPos) {
this.startPos = startPos;
}
public int getEndPos() {
return endPos;
}
public void setEndPos(int endPos) {
this.endPos = endPos;
}
public int getCompeleteSize() {
return compeleteSize;
}
public void setCompeleteSize(int compeleteSize) {
this.compeleteSize = compeleteSize;
}
@Override
public String toString() {
return "DownloadInfo [threadId=" + threadId + ", startPos=" + startPos
+ ", endPos=" + endPos + ", compeleteSize=" + compeleteSize
+ "]";
}
}
8.
public class DownloadUtil {
private DownloadHttpTool mDownloadHttpTool;
private OnDownloadListener onDownloadListener;
private int fileSize;
private int downloadedSize = 0;
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
int length = msg.arg1;
synchronized (this) {//加锁保证已下载的正确性
downloadedSize += length;
}
if (onDownloadListener != null) {
onDownloadListener.downloadProgress(downloadedSize);
}
if (downloadedSize >= fileSize) {
mDownloadHttpTool.compelete();
if (onDownloadListener != null) {
onDownloadListener.downloadEnd();
}
}
}
};
public DownloadUtil(int threadCount, String filePath, String filename,
String urlString, Context context) {
mDownloadHttpTool = new DownloadHttpTool(threadCount, urlString,
filePath, filename, context, mHandler);
}
//下载之前首先异步线程调用ready方法获得文件大小信息,之后调用开始方法
public void start() {
new AsyncTask<Void,Void,Void>() {
@Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
mDownloadHttpTool.ready();
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
fileSize = mDownloadHttpTool.getFileSize();
downloadedSize = mDownloadHttpTool.getCompeleteSize();
Log.w("Tag", "downloadedSize::" + downloadedSize);
if (onDownloadListener != null) {
onDownloadListener.downloadStart(fileSize);
}
mDownloadHttpTool.start();
}
}.execute();
}
public void pause() {
mDownloadHttpTool.pause();
}
public void delete(){
mDownloadHttpTool.delete();
}
public void reset(){
mDownloadHttpTool.delete();
start();
}
public void setOnDownloadListener(OnDownloadListener onDownloadListener) {
this.onDownloadListener = onDownloadListener;
}
//下载回调接口
public interface OnDownloadListener {
public void downloadStart(int fileSize);
public void downloadProgress(int downloadedSize);//记录当前所有线程下总和
public void downloadEnd();
}
}
9.
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private ProgressBar mProgressBar;
private Button start;
private Button pause;
private Button bo;
// private VideoView vv;
private TextView total;
private int max;
private DownloadUtil mDownloadUtil;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
total = (TextView) findViewById(R.id.textView);
start = (Button) findViewById(R.id.start);
pause = (Button) findViewById(R.id.delete);
bo = (Button) findViewById(R.id.bo);
// vv = (VideoView) findViewById(R.id.video_view);
// Intent intent=getIntent();
// String mp4 = intent.getStringExtra("mp4");
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
String urlString = "http://2449.vod.myqcloud.com/2449_22ca37a6ea9011e5acaaf51d105342e3.f20.mp4";
String localPath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/local2";
mDownloadUtil = new DownloadUtil(2, localPath, "adc.mp4", urlString,
this);
mDownloadUtil.setOnDownloadListener(new DownloadUtil.OnDownloadListener() {
@Override
public void downloadStart(int fileSize) {
// TODO Auto-generated method stub
Log.w(TAG, "fileSize::" + fileSize);
max = fileSize;
mProgressBar.setMax(fileSize);
}
@Override
public void downloadProgress(int downloadedSize) {
// TODO Auto-generated method stub
Log.w(TAG, "Compelete::" + downloadedSize);
mProgressBar.setProgress(downloadedSize);
total.setText((int) downloadedSize * 100 / max + "%");
}
@Override
public void downloadEnd() {
// TODO Auto-generated method stub
Log.w(TAG, "ENd");
// Uri rawUri = Uri.parse(Environment.getExternalStorageDirectory()
// .getAbsolutePath() + "/local2/adc.mp4");
// vv.setVideoURI(rawUri);
// vv.start();
}
});
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
mDownloadUtil.start();
}
});
pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
mDownloadUtil.pause();
}
});
bo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,ShowActivity.class);
//intent.putExtra("mp4",beanList.get(position).getVedio_url());
startActivity(intent);
}
});
}
}
10.
public class ShowActivity extends AppCompatActivity implements Iview {
private Banner mBan;
List<String> list = new ArrayList<>();
private RecyclerView mRecy;
//private VideoView videoView;
private static final String TAG = MainActivity.class.getSimpleName();
private ProgressBar mProgressBar;
private Button start;
private Button pause;
private Button bo;
private VideoView vv;
private TextView total;
private int max;
private DownloadUtil mDownloadUtil;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//初始化 Fresco
Fresco.initialize(this);
setContentView(R.layout.activity_show);
//隐藏标题
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
//-------------------------------------------------------
vv = (VideoView) findViewById(R.id.video_view);
Uri rawUri = Uri.parse(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/local2/adc.mp4");
vv.setVideoURI(rawUri);
vv.start();
//----------------------------------------------------------
initView();
okUrlBanner();
MyPresenter presenter = new MyPresenter(this);
presenter.loadData();
}
private void initView() {
mBan = (Banner) findViewById(R.id.ban);
mRecy = (RecyclerView) findViewById(R.id.recy);
// videoView= (VideoView) findViewById(R.id.video_view);
//创建布局管理器
LinearLayoutManager ll = new LinearLayoutManager(this);
mRecy.setLayoutManager(ll);
}
//Banner轮播
private void okUrlBanner() {
OkHttpUtils.getInstance().doGet(Api.BanUrl, new OnUiCallback() {
@Override
public void onFailed(Call call, IOException e) {
Log.i("1111", "onFailed: "+e);
}
@Override
public void onSuccess(String result) throws IOException {
Gson gson = new Gson();
Beans beans = gson.fromJson(result, Beans.class);
Log.i("2222", "onFailed: "+beans);
for (int i = 0; i < beans.getData().size(); i++) {
list.add(beans.getData().get(i).getImage_url());
}
mBan.setImageLoader(new Img());
mBan.setImages(list);
mBan.start();
}
});
}
//请求数据
@Override
public void setData(final List<Beans.DataBean> beanList) {
//创建适配器
ShowAdapter showAdapter = new ShowAdapter(ShowActivity.this, beanList);
mRecy.setAdapter(showAdapter);
//条目点击
showAdapter.setmOnItemClickListener(new ShowAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(ShowActivity.this,"点击下载播放",Toast.LENGTH_SHORT).show();
Intent intent=new Intent(ShowActivity.this,MainActivity.class);
//intent.putExtra("mp4",beanList.get(position).getVedio_url());
startActivity(intent);
}
});
}
}
10.
@Entity
public class User {
@Id
private Long id;
private Integer thread_id;
private Integer start_pos;
private Integer end_pos;
private Integer compelete_size;
private String url;
@Generated(hash = 2041931179)
public User(Long id, Integer thread_id, Integer start_pos, Integer end_pos,
Integer compelete_size, String url) {
this.id = id;
this.thread_id = thread_id;
this.start_pos = start_pos;
this.end_pos = end_pos;
this.compelete_size = compelete_size;
this.url = url;
}
@Generated(hash = 586692638)
public User() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getThread_id() {
return this.thread_id;
}
public void setThread_id(Integer thread_id) {
this.thread_id = thread_id;
}
public Integer getStart_pos() {
return this.start_pos;
}
public void setStart_pos(Integer start_pos) {
this.start_pos = start_pos;
}
public Integer getEnd_pos() {
return this.end_pos;
}
public void setEnd_pos(Integer end_pos) {
this.end_pos = end_pos;
}
public Integer getCompelete_size() {
return this.compelete_size;
}
public void setCompelete_size(Integer compelete_size) {
this.compelete_size = compelete_size;
}
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
}