最新GreenDao多线程下载,断点续传,播放视频
来源:互联网 发布:xp ie8 淘宝 版本过低 编辑:程序博客网 时间:2024/05/16 15:52
最上面是一个Banner的轮播图,中间是一个GreenDao下载视频播放,下面是一个RecyclerView的条目点击事件
添加了泛型和解绑,抽基类,完美结合
先看一下效果图
在清单文件里加权限,初始化Appliction
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.bawei.tangxiaoying.greendao"> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> <application android:name="com.bawei.tangxiaoying.greendao.App" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".ShowActivity">//我这里先运行的是ShowActivity <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".MainActivity"></activity> </application></manifest>
添加依赖
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'
布局
activity——main
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginLeft="23dp" android:layout_marginStart="23dp" android:layout_marginTop="18dp" android:text="TextView" /> <ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="fill_parent" android:layout_height="7.5dp" android:layout_below="@+id/textView" android:layout_marginRight="8dp" android:max="100" android:progress="100" android:visibility="visible" /> <!--<VideoView--> <!--android:id="@+id/video_view"--> <!--android:layout_below="@+id/progressBar"--> <!--android:layout_width="match_parent"--> <!--android:layout_height="200dp"--> <!--android:layout_marginTop="20dp"--> <!--/>--> <Button android:id="@+id/start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_toEndOf="@+id/textView" android:layout_toRightOf="@+id/textView" android:text="下载" /> <Button android:id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginLeft="48dp" android:layout_marginStart="48dp" android:layout_toEndOf="@+id/start" android:layout_toRightOf="@+id/start" android:text="暂停" /> <Button android:id="@+id/bo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginLeft="48dp" android:layout_marginStart="48dp" android:layout_toEndOf="@+id/delete" android:layout_toRightOf="@+id/delete" android:text="播放" /></RelativeLayout>
show_Activity
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <com.youth.banner.Banner android:id="@+id/ban" android:layout_width="match_parent" android:layout_height="200dp" android:layout_alignParentTop="true" android:layout_alignParentStart="true"></com.youth.banner.Banner> <VideoView android:id="@+id/video_view" android:layout_below="@+id/ban" android:layout_width="match_parent" android:layout_height="200dp" android:layout_marginTop="20dp" /> <!--<RelativeLayout--> <!--android:layout_below="@+id/ban"--> <!--android:id="@+id/bofang"--> <!--android:layout_width="match_parent"--> <!--android:layout_height="200dp">--> <!--<TextView--> <!--android:id="@+id/textView"--> <!--android:layout_width="wrap_content"--> <!--android:layout_height="wrap_content"--> <!--android:layout_alignParentLeft="true"--> <!--android:layout_alignParentStart="true"--> <!--android:layout_alignParentTop="true"--> <!--android:layout_marginLeft="23dp"--> <!--android:layout_marginStart="23dp"--> <!--android:layout_marginTop="18dp"--> <!--android:text="TextView" />--> <!--<ProgressBar--> <!--android:id="@+id/progressBar"--> <!--style="?android:attr/progressBarStyleHorizontal"--> <!--android:layout_width="fill_parent"--> <!--android:layout_height="7.5dp"--> <!--android:layout_below="@+id/textView"--> <!--android:layout_marginRight="8dp"--> <!--android:max="100"--> <!--android:progress="100"--> <!--android:visibility="visible" />--> <!--<VideoView--> <!--android:id="@+id/video_view"--> <!--android:layout_below="@+id/progressBar"--> <!--android:layout_width="match_parent"--> <!--android:layout_height="200dp"--> <!--android:layout_marginTop="20dp"--> <!--/>--> <!--<Button--> <!--android:id="@+id/start"--> <!--android:layout_width="wrap_content"--> <!--android:layout_height="wrap_content"--> <!--android:layout_alignParentBottom="true"--> <!--android:layout_toEndOf="@+id/textView"--> <!--android:layout_toRightOf="@+id/textView"--> <!--android:text="下载" />--> <!--<Button--> <!--android:id="@+id/delete"--> <!--android:layout_width="wrap_content"--> <!--android:layout_height="wrap_content"--> <!--android:layout_alignParentBottom="true"--> <!--android:layout_marginLeft="48dp"--> <!--android:layout_marginStart="48dp"--> <!--android:layout_toEndOf="@+id/start"--> <!--android:layout_toRightOf="@+id/start"--> <!--android:text="暂停" />--> <!--<Button--> <!--android:id="@+id/bo"--> <!--android:layout_width="wrap_content"--> <!--android:layout_height="wrap_content"--> <!--android:layout_alignParentBottom="true"--> <!--android:layout_marginLeft="48dp"--> <!--android:layout_marginStart="48dp"--> <!--android:layout_toEndOf="@+id/delete"--> <!--android:layout_toRightOf="@+id/delete"--> <!--android:text="播放" />--> <!--</RelativeLayout>--> <android.support.v7.widget.RecyclerView android:id="@+id/recy" android:layout_below="@+id/video_view" android:layout_width="match_parent" android:layout_height="wrap_content"></android.support.v7.widget.RecyclerView></RelativeLayout>
rcy_item
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" xmlns:fresco="http://schemas.android.com/apk/res-auto" android:layout_height="match_parent" android:orientation="horizontal" > <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/img" android:layout_width="120dp" android:layout_height="120dp" android:src="@mipmap/ic_launcher" android:layout_margin="10dp" /> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:maxLines="2" android:text="26565465465446" android:textSize="13dp" android:textColor="#A9A9A9" ></TextView></LinearLayout>
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);}
MyModel
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); }}
Ipp解绑
//接口public interface Ipp<T> { //方法:1.绑定方法 2.解绑的方法 public void attch(T view); public void detch();}
Presenter加了泛型和软引用解绑
public class MyPresenter implements Ipp<Iview>{ IModel model; Iview view; SoftReference<Iview> softReference;//软引用 public MyPresenter(Iview view) { this.view = view; model=new MyModel(); attch(view); } 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()); softReference.get().setData(data); // view.setData(data); } }); } @Override public void attch(Iview view) { softReference=new SoftReference<Iview>(view); } @Override public void detch() { softReference.clear(); }}
Banner轮播时使用
OkHttpUtils
public class OkHttpUtils { 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().newBuilder().build(); } } public void doGet(String url, Callback callback){ initOkHttpClient(); Request request=new Request.Builder().url(url).build(); Call call=client.newCall(request); call.enqueue(callback); }}OkUiCallback
public abstract class OnUiCallback implements Callback { private Handler handler=OkHttpUtils.getInstance().getHandler(); public abstract void onFailed(Call call,IOException e); public abstract void onSuccess(String result)throws IOException; @Override public void onFailure(final Call call, final IOException e) { handler.post(new Runnable() { @Override public void run() { onFailure(call,e); } }); } @Override public void onResponse(Call call, final Response response) throws IOException { final String result=response.body().string(); handler.post(new Runnable() { @Override public void run() { try { onSuccess(result); } catch (IOException e) { e.printStackTrace(); } } }); }}
Img
public class Img extends ImageLoader { @Override public void displayImage(Context context, Object path, ImageView imageView) { Glide.with(context) .load(path) .into(imageView); }}
Api
public class Api { //public static final String BanUrl="http://news-at.zhihu.com/api/4/news/latest"; public static final String BanUrl="http://result.eolinker.com/iYXEPGn4e9c6dafce6e5cdd23287d2bb136ee7e9194d3e9?uri=vedio";}
RequestApi
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);}
Retorfit封装
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); }}
ShowAdapter
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); } }}
Bean类
import java.util.List;/** * * http://result.eolinker.com/iYXEPGn4e9c6dafce6e5cdd23287d2bb136ee7e9194d3e9?uri=vedio* */public class Beans { private int code; private String msg; private List<DataBean> data; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public List<DataBean> getData() { return data; } public void setData(List<DataBean> data) { this.data = data; } public static class DataBean { /** * content : 习近平举行仪式欢迎加蓬总统访华 * id : 10000 * image_url : http://pic32.nipic.com/20130817/9745430_101836881000_2.jpg * title : 今日头条 * type : 1 * vedio_url : http://2449.vod.myqcloud.com/2449_bfbbfa3cea8f11e5aac3db03cda99974.f20.mp4 */ private String content; private int id; private String image_url; private String title; private int type; private String vedio_url; public String getContent() { return content; } public void setContent(String content) { this.content = content; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getImage_url() { return image_url; } public void setImage_url(String image_url) { this.image_url = image_url; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public int getType() { return type; } public void setType(int type) { this.type = type; } public String getVedio_url() { return vedio_url; } public void setVedio_url(String vedio_url) { this.vedio_url = vedio_url; } }}
GreenDao多线程下载,断点续传部分
先集成GreenDao,在我的博客里有集成GreenDao的步骤,可参考
注意GreenDao的依赖必须是3.2.0的,不然会报错
compile 'org.greenrobot:greendao:3.2.0'
BaseActivity基类
//创建的Activity继承泛型<T extends Ipp>public abstract class BaseActivity<T extends Ipp> extends AppCompatActivity { //定义属性 T presenter; @Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); //定义抽象方法 createpresenter(); } protected abstract void createpresenter(); //销毁的方法 @Override protected void onDestroy() { super.onDestroy(); presenter.detch(); }}
首页 第一个页面 ShowActivity
showActivity继承BaseActivity基类
public class ShowActivity extends BaseActivity<MyPresenter> 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();// 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();// }// }); //---------------------------------------------------------- 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); } }); } //解绑 @Override protected void createpresenter() { }}
跳转的第二个GreenDao下载页面
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); } }); }}
App
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(); }}User
@Entitypublic 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; }}
DownloadUtils
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(); }}DownloadInfo
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 + "]"; }}
DownloadHttpTool
ublic 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(); } } } }}DownLoadSqlTool
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(); }}
阅读全文
0 0
- 最新GreenDao多线程下载,断点续传,播放视频
- 多线程下载+断点续传+播放视频
- retrofit+Rxjava+Greendao+断点续传+Ijkplayer视频播放
- GreenDao实现多线程下载与断点续传
- 多线程下载+视频播放
- Greendao+多线程断点续传
- Greendao+多线程断点续传
- Greendao+多线程断点续传
- Greendao+多线程断点续传
- Greendao+多线程断点续传
- Greendao+多线程断点续传
- 多线程断点续传+GreenDao
- 多线程断点续传GreenDao版
- Greendao+多线程断点续传
- 利用GreenDao多线程断点续传
- Android Greendao+多线程断点续传
- GreenDao+多线程断点续传
- android 多线程下载+GreenDao保存状态+ijkplayer播放缓存后的视频
- Win 10 安装caffe
- 计蒜客 宝藏 (状压DP)
- 剑指offer-用两个栈实现队列
- android 多线程断点续传下载(可运行)
- PHP正则匹配
- 最新GreenDao多线程下载,断点续传,播放视频
- spring的@Transactional注解详细用法
- c++中好用的stringstream
- 【java 多线程】多线程并发同步问题及生产者、消费者问题
- 第十二周项目4-Floyd算法验证
- c#获取字符串长度
- 使用HAProxy、PHP、Redis和MySQL支撑10亿请求每周架构细节
- Ijikplayer的简单使用
- android中流式布局