diff --git a/zhuike/src/main/AndroidManifest.xml b/zhuike/src/main/AndroidManifest.xml
index 520db16..77f87af 100644
--- a/zhuike/src/main/AndroidManifest.xml
+++ b/zhuike/src/main/AndroidManifest.xml
@@ -12,51 +12,42 @@
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
+ android:launchMode="singleInstance"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/ToolBarTheme"
- android:launchMode="singleInstance"
android:usesCleartextTraffic="true">
-
+
-
-
-
-
-
+ android:theme="@style/ToolBarTheme.NoActionBar">
-
+ android:theme="@style/ToolBarTheme.NoActionBar">
@@ -64,28 +55,26 @@
-
-
-
-
+ android:theme="@style/ToolBarTheme.NoActionBar">
-
+ android:theme="@style/ToolBarTheme.NoActionBar">
-
-
-
-
+ android:theme="@style/ToolBarTheme.NoActionBar">
+
+
\ No newline at end of file
diff --git a/zhuike/src/main/assets/litepal.xml b/zhuike/src/main/assets/litepal.xml
index f9ad3e5..eec8672 100644
--- a/zhuike/src/main/assets/litepal.xml
+++ b/zhuike/src/main/assets/litepal.xml
@@ -2,7 +2,7 @@
-
+
diff --git a/zhuike/src/main/java/com/novelbook/android/Activity_cache.java b/zhuike/src/main/java/com/novelbook/android/Activity_cache.java
new file mode 100644
index 0000000..7438b59
--- /dev/null
+++ b/zhuike/src/main/java/com/novelbook/android/Activity_cache.java
@@ -0,0 +1,359 @@
+package com.novelbook.android;
+
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.novelbook.android.Activity_base;
+import com.novelbook.android.R;
+import com.novelbook.android.bean.Cataloge;
+import com.novelbook.android.db.Chapter;
+import com.novelbook.android.db.DownloadTask;
+import com.novelbook.android.db.Novel;
+import com.novelbook.android.service.ServiceDownload;
+import com.novelbook.android.utils.ImageUtil;
+
+import org.litepal.LitePal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+public class Activity_cache extends Activity_base {
+ public static final String TAG=Activity_cache.class.getSimpleName();
+ @BindView(R.id.recycleView)
+ RecyclerView mRecyclerView;
+ private List mData;
+ private CacheAdapter mAdapter;
+ @Override
+ public int getLayoutRes() {
+ return R.layout.activitycache;
+ }
+
+ @Override
+ protected void initViews() {
+
+ }
+
+ @Override
+ protected void setTitle() {
+
+ }
+
+ @Override
+ protected void initData() {
+ initiDownloadReceiver();
+ mData = LitePal.findAll(DownloadTask.class);
+
+ mAdapter = new CacheAdapter(this,mData,R.layout.recycle_list_item_cache,new OnItemClickLitener() {
+ @Override
+ public void onItemClick(View view, int position) {
+ Novel novel = LitePal.find(Novel.class,mData.get(position).getNovelId());
+ showBookDetail(novel);
+ }
+
+ @Override
+ public void onItemLongClick(View view, int position)
+ {
+ final AlertDialog.Builder normalDialog =
+ new AlertDialog.Builder(Activity_cache.this);
+
+ normalDialog.setTitle("删除此下载任务并清除缓存吗");
+ normalDialog.setMessage("确定删除吗?");
+ normalDialog.setPositiveButton("取消",
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+
+ }
+ });
+ normalDialog.setNegativeButton("删除",
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ DownloadTask cl = mData.get(position);
+ cl.delete();
+ // Chapter.deleteByTask();
+ //TODO:clear cache ?
+
+
+ mAdapter.removeData(position);
+
+ }
+ });
+
+ normalDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+
+ }
+ });
+ // 显示
+ normalDialog.show();
+ // mAdapter.removeData(position);
+ }
+
+ });
+
+ mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
+ mRecyclerView.setAdapter(mAdapter );
+
+
+
+ }
+
+ @Override
+ public void fillData() {
+
+ }
+
+ private IntentFilter filter;
+ DownloadProcessReceiver receiver;
+ void initiDownloadReceiver(){
+ filter = new IntentFilter("ServiceDownload.ChapterContent.finished");
+ filter.addCategory(Intent.CATEGORY_DEFAULT);
+ receiver = new DownloadProcessReceiver();
+ }
+ class DownloadProcessReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent){
+ int taskId =0;
+ int progress=0;
+
+ if( intent.hasExtra("progress")){
+ progress = intent.getIntExtra("progress",0);
+ }
+ if( intent.hasExtra("taskId")){
+ taskId = intent.getIntExtra("taskId",0);
+ }
+
+ Log.d(TAG, String.format("onReceive: taskId %s progress %s ",taskId,progress));
+ for(DownloadTask dt : mData){
+ if(taskId == dt.getId()){
+ dt.setFinishedChpats(progress);
+ if(dt.getDownSatus()!=DownloadTask.DownStatus.等待下载) {
+ dt.setDownSatus(DownloadTask.DownStatus.正在下载);
+ }
+ }else{
+ if(dt.getDownSatus()!=DownloadTask.DownStatus.正在下载) {
+ dt.setDownSatus(DownloadTask.DownStatus.排队中);
+ }
+ }
+ }
+
+ mAdapter.setData(mData);
+
+
+ }
+ }
+ private void startDownloadService(int taskId,boolean start) {
+ Intent serviceIntent = new Intent(this, ServiceDownload.class);
+ serviceIntent.putExtra("taskId",taskId);
+ serviceIntent.putExtra("start",start);
+ startService(serviceIntent);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ registerReceiver(receiver, filter);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ unregisterReceiver(receiver);
+ }
+
+ class CacheAdapter extends RecyclerView.Adapter {
+ private final int EMPTY_VIEW = 1;
+ private final int PROGRESS_VIEW = 2;
+ private final int IMAGE_VIEW = 3;
+
+ private Context context;
+ private List mDatas = new ArrayList();
+ private OnItemClickLitener mOnItemClickLitener;
+ private int listItemID;
+
+ public CacheAdapter(Context context, List mDatas, int listItemID, OnItemClickLitener clickLitener) {
+ this.context = context;
+ this.mDatas = mDatas;
+ this.mOnItemClickLitener = clickLitener;
+ this.listItemID = listItemID;
+ }
+
+ public CacheAdapter(Context context, OnItemClickLitener clickLitener) {
+ this.context = context;
+ this.mOnItemClickLitener = clickLitener;
+
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (mDatas.size() == 0) {
+ return EMPTY_VIEW;
+ } else if (mDatas.get(position) == null) {
+ return PROGRESS_VIEW;
+ } else {
+ return super.getItemViewType(position);
+ }
+ }
+
+ @Override
+ public CacheAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ CacheAdapter.MyViewHolder holder = new CacheAdapter.MyViewHolder(LayoutInflater.from(
+ context).inflate(listItemID, parent,
+ false));
+ return holder;
+ }
+
+
+ public void setParameters(List mDatas, int listItemID) {
+ this.mDatas = mDatas;
+ this.listItemID = listItemID;
+ }
+
+ public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener) {
+ this.mOnItemClickLitener = mOnItemClickLitener;
+ }
+
+ @Override
+ public void onBindViewHolder(CacheAdapter.MyViewHolder holder, int position) {
+ holder.tvTitle.setText(mDatas.get(position).getNovelTitle());
+ holder.tvSource.setText(mDatas.get(position).getDomainName());
+ boolean finished = mData.get(position).getFinishedChpats() == mData.get(position).getTotalChapts();
+
+ if( mData.get(position).getTotalChapts() >0) {
+ float progress = mData.get(position).getFinishedChpats() *100/ mData.get(position).getTotalChapts() ;
+ holder.tvProgress.setText(String.format("%s/%s",mData.get(position).getFinishedChpats() , mData.get(position).getTotalChapts()));
+
+ holder.tvStatus.setText( mData.get(position).getDownSatus() == DownloadTask.DownStatus.正在下载 ?"正在下载"
+ : mData.get(position).getDownSatus() == DownloadTask.DownStatus.等待下载? "暂停下载" :"休眠中");
+
+ holder.tvStatus.setText( mData.get(position).getStatus()==0 || mData.get(position).getFinishedChpats() >=mData.get(position).getTotalChapts()
+ ? holder.tvStatus.getText():"下载完成" );
+
+ holder.tvStatus.setText( mData.get(position).getStatus()==0? holder.tvStatus.getText():"下载完成" );
+
+ holder.tvStatus.setText( mData.get(position).getDownSatus() == DownloadTask.DownStatus.排队中?"排队中": holder.tvStatus.getText() );
+
+ holder.barProgress.setProgress((int)progress);
+ }
+ // holder.imgStart.setVisibility(View.GONE);
+ int img = R.mipmap.play;
+ img = mData.get(position).getDownSatus() == DownloadTask.DownStatus.正在下载 ? R.mipmap.pause : R.mipmap.play;
+
+ holder.imgStart.setImageResource( img);
+ holder.imgStart.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int pos = holder.getLayoutPosition();
+
+ if(mData.get(position).getDownSatus() != DownloadTask.DownStatus.正在下载) {
+ startDownloadService(mData.get(pos).getId(),true);
+ holder.imgStart.setImageResource( R.mipmap.pause);
+ mData.get(pos).setDownSatus(DownloadTask.DownStatus.排队中);
+
+ }else{
+ startDownloadService(mData.get(pos).getId(),false);
+ holder.imgStart.setImageResource( R.mipmap.play);
+ mData.get(pos).setDownSatus(DownloadTask.DownStatus.等待下载);
+ }
+ mData.get(pos).update( mData.get(pos).getId());
+
+
+ }
+ });
+
+ // 如果设置了回调,则设置点击事件
+ if (mOnItemClickLitener != null) {
+ holder.itemView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int pos = holder.getLayoutPosition();
+ mOnItemClickLitener.onItemClick(holder.itemView, pos);
+ }
+ });
+ }
+
+ holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ int pos = holder.getLayoutPosition();
+ mOnItemClickLitener.onItemLongClick(holder.itemView, pos);
+ return false;
+ }
+ });
+
+ }
+
+ @Override
+ public int getItemCount() {
+ return mDatas.size();
+ }
+
+ public void addData(int position) {
+ // mDatas.add(position, "Insert One");
+ // notifyItemInserted(position);
+ }
+
+ public void removeData(int position) {
+ mDatas.remove(position);
+ notifyItemRemoved(position);
+ notifyDataSetChanged();
+ }
+
+ public void setData(List data) {
+ mData = data;
+ notifyDataSetChanged();
+ }
+
+ class MyViewHolder extends RecyclerView.ViewHolder {
+ @BindView(R.id.tvTitle)
+ TextView tvTitle;
+ @BindView(R.id.tvProgress)
+ TextView tvProgress;
+ @BindView(R.id.tvStatus)
+ TextView tvStatus;
+ @BindView(R.id.barProgress)
+ ProgressBar barProgress;
+ @BindView(R.id.imgStart)
+ ImageView imgStart;
+ @BindView(R.id.tvSource)
+ TextView tvSource;
+ public MyViewHolder(View view) {
+ super(view);
+ ButterKnife.bind(this, view);
+ //tvTitle = (TextView) view.findViewById(R.id.title);
+ // tvAuthor = (TextView) view.findViewById(R.id.author);
+
+ }
+ }
+ }
+ interface OnItemClickLitener
+ {
+ void onItemClick(View view, int position);
+
+ void onItemLongClick(View itemView, int pos);
+ }
+
+
+}
diff --git a/zhuike/src/main/java/com/novelbook/android/Activity_paihangbang.java b/zhuike/src/main/java/com/novelbook/android/Activity_paihangbang.java
index ce8032b..4ba1212 100644
--- a/zhuike/src/main/java/com/novelbook/android/Activity_paihangbang.java
+++ b/zhuike/src/main/java/com/novelbook/android/Activity_paihangbang.java
@@ -29,9 +29,9 @@ public static String TAG ="com.novelbook.android.paihangbang";
ViewPager mViewpager;
@BindView(R.id.tab_layout)
SlidingTabLayout tabLayout;
- public static String EXTR_FN="fn";
- public static String EXTR_TITLE="title";
- public static String EXTR_BANGDAN ="bangdan";
+ public static final String EXTR_FN="fn";
+ public static final String EXTR_TITLE="title";
+ public static final String EXTR_BANGDAN ="bangdan";
public static final String EXTR_SEARCH ="search";
public static final String EXTR_HISTORY ="history" ;
private ArrayList mFragments;
diff --git a/zhuike/src/main/java/com/novelbook/android/BookActivity.java b/zhuike/src/main/java/com/novelbook/android/BookActivity.java
index 84a45e1..5ed9400 100644
--- a/zhuike/src/main/java/com/novelbook/android/BookActivity.java
+++ b/zhuike/src/main/java/com/novelbook/android/BookActivity.java
@@ -353,6 +353,10 @@ public class BookActivity extends Activity_base {
Toast.makeText(BookActivity.this, "已加入下载队列1", Toast.LENGTH_LONG).show();
} else if (msg.what == 3) {
Toast.makeText(BookActivity.this, "获取目录信息失败,下载失败", Toast.LENGTH_LONG).show();
+ }else if (msg.what == 4) {
+ Toast.makeText(BookActivity.this, String.format("亲,小说《%s》已经缓存完成了", mNovel.getName()), Toast.LENGTH_LONG).show();
+ }else if (msg.what == 5) {
+ Toast.makeText(BookActivity.this, String.format("亲,小说《%s》已经在缓存队列了,请耐心等待", mNovel.getName()), Toast.LENGTH_LONG).show();
}
hideProgress();
}
@@ -420,20 +424,7 @@ public class BookActivity extends Activity_base {
// if (LitePal.where("novelId = ?", mNovel.getId() + "").count("DownloadTask") > 0) {
- List dts = LitePal.where("novelId = ?", mNovel.getId() + "").limit(1).find(DownloadTask.class);
- if (dts.size() > 0) {
- if (dts.get(0).getStatus() == 1) {
- Toast.makeText(this, String.format("亲,小说《%s》已经缓存完成了", mNovel.getName()), Toast.LENGTH_LONG).show();
- } else {
- Toast.makeText(this, String.format("亲,小说《%s》已经在缓存队列了,请耐心等待", mNovel.getName()), Toast.LENGTH_LONG).show();
- startDownloadService(dts.get(0).getId());
- // startService( getSvrIntent());
- }
-
- return;
-
- }
// }
@@ -454,16 +445,40 @@ public class BookActivity extends Activity_base {
handler.sendEmptyMessage(3);
} else {
+
+
+ List dts = LitePal.where("novelId = ? and domain =?", mNovel.getId() + "",mNovel.getDomain()).limit(1).find(DownloadTask.class);
+ if (dts.size() > 0) {
+ if (dts.get(0).getStatus() == 1) {
+
+ handler.sendEmptyMessage(4);
+
+ } else {
+ handler.sendEmptyMessage(5);
+
+ startDownloadService(dts.get(0).getId());
+ // startService( getSvrIntent());
+ }
+
+ return;
+
+ }
+
DownloadTask dt = new DownloadTask();
dt.setDomain(mNovel.getDomain());
+ dt.setDomainName(mNovel.getDomainName());
dt.setFinishedChpats(0);
dt.setNovelId(mNovel.getId());
dt.setStatus(0);
- dt.setTotalChapts(mNovel.getTotalChapts());
+ // dt.setTotalChapts(mNovel.getChaptCnt());
+ dt.setTotalChapts(pageFactory.getChapters().size());
+ dt.setNovelTitle(mNovel.getName());
+
dt.save();
// LitePal.deleteAll("chapter","novelId=?",mNovel.getId()+"");
for (Chapter chapter : pageFactory.getChapters()) {
chapter.setNovelId(mNovel.getId());
+ chapter.setTaskId(dt.getId());
chapter.save();
}
startDownloadService(dt.getId());
diff --git a/zhuike/src/main/java/com/novelbook/android/Main2Activity.java b/zhuike/src/main/java/com/novelbook/android/Main2Activity.java
index c0c2eee..62cf466 100644
--- a/zhuike/src/main/java/com/novelbook/android/Main2Activity.java
+++ b/zhuike/src/main/java/com/novelbook/android/Main2Activity.java
@@ -31,6 +31,7 @@ import com.novelbook.android.Fragments.Fragment_paihang;
import com.novelbook.android.netsubscribe.BookSubscribe;
import com.novelbook.android.netutils.OnSuccessAndFaultListener;
import com.novelbook.android.netutils.OnSuccessAndFaultSub;
+import com.novelbook.android.service.ServiceDownload;
import com.novelbook.android.utils.Config;
import com.novelbook.android.utils.Constants;
import com.novelbook.android.utils.GsonUtil;
@@ -268,8 +269,10 @@ public class Main2Activity extends Activity_base
intent.putExtra(Activity_paihangbang.EXTR_HISTORY,"yes");
intent.putExtra(Activity_paihangbang.EXTR_TITLE,"我曾经看过的书");
startActivity(intent);
- } else if (id == R.id.nav_slideshow) {
-
+ } else if (id == R.id.nav_huancun) {
+ startDownloadService();
+ Intent intent = new Intent(Main2Activity.this,Activity_cache.class);
+ startActivity(intent);
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
@@ -282,7 +285,11 @@ public class Main2Activity extends Activity_base
drawer.closeDrawer(GravityCompat.START);
return true;
}
+ private void startDownloadService() {
+ Intent serviceIntent = new Intent(this, ServiceDownload.class);
+ startService(serviceIntent);
+ }
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
diff --git a/zhuike/src/main/java/com/novelbook/android/db/Chapter.java b/zhuike/src/main/java/com/novelbook/android/db/Chapter.java
index 5b64309..f8dce80 100644
--- a/zhuike/src/main/java/com/novelbook/android/db/Chapter.java
+++ b/zhuike/src/main/java/com/novelbook/android/db/Chapter.java
@@ -1,12 +1,17 @@
package com.novelbook.android.db;
+import android.text.TextUtils;
+
import org.litepal.LitePal;
import org.litepal.crud.LitePalSupport;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.List;
+import javax.security.auth.callback.CallbackHandler;
+
public class Chapter extends LitePalSupport implements Serializable {
private int id;
@@ -19,6 +24,9 @@ public class Chapter extends LitePalSupport implements Serializable {
private String chapterPath; //缓存地址
private String domain; //目标 site
private int index;//第几章
+ private int taskId;
+
+
public static Chapter getChapter(int id, String domain, int chapId) {
// Chapter chapter =(Chapter)
@@ -37,7 +45,13 @@ public class Chapter extends LitePalSupport implements Serializable {
chapter.setChapterPath("");
return chapter;
}
+ public int getTaskId() {
+ return taskId;
+ }
+ public void setTaskId(int taskId) {
+ this.taskId = taskId;
+ }
public int getIndex() {
return index;
}
@@ -118,10 +132,18 @@ public class Chapter extends LitePalSupport implements Serializable {
this.chapterPath = chapterPath;
}
- public static List getUnCachedChapters(int noveId,String domain ){
+ public static List getUnCachedChapters(int taskId){
// return LitePal.where("novelId = ? and domain = ? and chapterPath = null" ,noveId+"",domain ) .find(Chapter.class);
-
- return LitePal.where("novelId = ? and domain = ? " ,noveId+"",domain).find(Chapter.class);
+ //ist lst = LitePal.where("novelId = ? and domain = ? " ,noveId+"",domain).find(Chapter.class);
+ List lst = LitePal.where("taskId= ? " ,taskId+"").find(Chapter.class);
+ List lstrt = new ArrayList();
+ for(Chapter chapter : lst){
+ if(TextUtils.isEmpty(chapter.getChapterPath())){
+ lstrt.add(chapter);
+ }
+ }
+ return lstrt;
+ // return LitePal.where("novelId = ? and domain = ? " ,noveId+"",domain).find(Chapter.class);
}
diff --git a/zhuike/src/main/java/com/novelbook/android/db/DownloadTask.java b/zhuike/src/main/java/com/novelbook/android/db/DownloadTask.java
index 336e18e..9f56a5d 100644
--- a/zhuike/src/main/java/com/novelbook/android/db/DownloadTask.java
+++ b/zhuike/src/main/java/com/novelbook/android/db/DownloadTask.java
@@ -9,11 +9,38 @@ public class DownloadTask extends LitePalSupport implements Serializable {
private int id;
private int novelId;
+ private String novelTitle;
private String domain;
+ private String domainName;
@Column( defaultValue = "0")
private int status; //0 未完成 1 完成
private int totalChapts;
private int finishedChpats;
+ private DownStatus downSatus =DownStatus.初始状态;//0 队列外 1 队列内
+
+ public DownStatus getDownSatus() {
+ return downSatus;
+ }
+
+ public void setDownSatus(DownStatus downSatus) {
+ this.downSatus = downSatus;
+ }
+
+ public String getNovelTitle() {
+ return novelTitle;
+ }
+
+ public void setNovelTitle(String novelTitle) {
+ this.novelTitle = novelTitle;
+ }
+
+ public String getDomainName() {
+ return domainName;
+ }
+
+ public void setDomainName(String domainName) {
+ this.domainName = domainName;
+ }
public int getTotalChapts() {
return totalChapts;
@@ -63,6 +90,9 @@ public class DownloadTask extends LitePalSupport implements Serializable {
this.status = status;
}
+ public static enum DownStatus{
+ 初始状态,等待下载, 正在下载,排队中,下载完成
+ }
}
diff --git a/zhuike/src/main/java/com/novelbook/android/db/Novel.java b/zhuike/src/main/java/com/novelbook/android/db/Novel.java
index 2f16d40..af88998 100644
--- a/zhuike/src/main/java/com/novelbook/android/db/Novel.java
+++ b/zhuike/src/main/java/com/novelbook/android/db/Novel.java
@@ -24,6 +24,7 @@ public class Novel extends LitePalSupport implements Serializable{
private String name;
private String infoUrl;
private String domain;
+ private String domainName;
private String muluUrl;
private String novelPath;
private long lastReadPos;
@@ -61,7 +62,13 @@ public class Novel extends LitePalSupport implements Serializable{
this.readtime = readtime;
}
+ public String getDomainName() {
+ return domainName;
+ }
+ public void setDomainName(String domainName) {
+ this.domainName = domainName;
+ }
public long getLastVisit() {
return lastVisit;
@@ -127,17 +134,7 @@ public class Novel extends LitePalSupport implements Serializable{
this.progress = progress;
}
- public int getTotalChapts() {
- return totalChapts;
- }
-
- public void setTotalChapts(int totalChapts) {
- this.totalChapts = totalChapts;
- }
-
- private int totalChapts;
-
- public int getId() {
+ public int getId() {
return id;
}
diff --git a/zhuike/src/main/java/com/novelbook/android/service/ServiceDownload.java b/zhuike/src/main/java/com/novelbook/android/service/ServiceDownload.java
index 807edbf..85ecc67 100644
--- a/zhuike/src/main/java/com/novelbook/android/service/ServiceDownload.java
+++ b/zhuike/src/main/java/com/novelbook/android/service/ServiceDownload.java
@@ -1,8 +1,11 @@
package com.novelbook.android.service;
import android.app.IntentService;
+import android.app.Service;
import android.content.Intent;
+import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
@@ -15,6 +18,7 @@ import com.novelbook.android.netutils.HttpMethods;
import com.novelbook.android.utils.BookUtil;
import com.novelbook.android.utils.NovelParseUtil;
+import com.novelbook.android.utils.PageFactory;
import org.json.JSONException;
import org.json.JSONObject;
@@ -41,7 +45,7 @@ import okhttp3.Response;
import okhttp3.ResponseBody;
-public class ServiceDownload extends IntentService {
+public class ServiceDownload extends Service {
private static final String TAG ="ServiceDownload" ;
private final String storagePath = BookUtil.storagePath;
@@ -57,9 +61,9 @@ public class ServiceDownload extends IntentService {
// public ServiceDownload(String name) {
// super(name);
// }
- public ServiceDownload() {
+ /* public ServiceDownload() {
super("ServiceDownload");
- }
+ }*/
private Map siteRuleMap = new HashMap() ; // key = novelId
private DownloadTask processingTask ;
@@ -67,6 +71,7 @@ public class ServiceDownload extends IntentService {
private int chaptIndex=0;
private Map> tasksMap = new ConcurrentHashMap>();// key = taskId
+ private Map> tasksMapDone = new ConcurrentHashMap>();// key = taskId
@Override
public void onCreate() {
@@ -91,18 +96,23 @@ public class ServiceDownload extends IntentService {
}
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId){
+ // // QLog.getLogger().d( TAG,TAG+"... service NaviSvc onStartCommand.....," );
+ onHandleIntent(intent);
+ // We want this service to continue running until it is explicitly
+ // stopped, so return sticky.
+// return START_NOT_STICKY; //TODO: checking why can not stop the service.
+ return START_STICKY;
+ }
+
+
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.d(TAG,"test service onStart");
}
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- Log.d(TAG,"test service onStartCommand");
- return super.onStartCommand(intent, flags, startId);
-
- }
@Override
public void onDestroy() {
@@ -110,65 +120,197 @@ public class ServiceDownload extends IntentService {
super.onDestroy();
}
+ @Override
+ public IBinder onBind(Intent intent) {
+ // TODO Auto-generated method stub
+ return null;
+ }
private List downloadTasks = new ArrayList();
-
- @Override
+
+ List cancelId =new ArrayList();
+
protected void onHandleIntent( Intent intent) {
- Log.d(TAG,"test service onHandleIntent...begin");
+ Log.d(TAG,"ServiceDownload onHandleIntent...begin");
String key ="taskId";
int taskId =0;
+
if(intent.hasExtra(key)){
taskId= intent.getExtras().getInt(key);
- startNewTask(taskId);
+ DownloadTask dt = LitePal.find(DownloadTask.class,taskId);
+
+ if(intent.hasExtra("start")){
+ if(!intent.getBooleanExtra("start",true)){
+ cancelId.add(taskId);
+ for(DownloadTask t : downloadTasks){
+ if( t.getId() == taskId){
+ t.setDownSatus(DownloadTask.DownStatus.等待下载);
+ break;
+ }
+ }
+ stopTask(taskId);
+
+ }else{
+ boolean newTask = true;
+
+ if(cancelId.contains(taskId)){
+ cancelId.remove(cancelId.indexOf(taskId));
+ }
+ for(DownloadTask t : downloadTasks){
+ if(t.getId() == taskId){
+ newTask =false;
+ break;
+ }
+ }
+
+ if(newTask) {
+ startNewTask(dt);
+ } else {
+
+ for (DownloadTask t : downloadTasks) {
+ if (t.getId() == taskId) {
+ t.setDownSatus(DownloadTask.DownStatus.正在下载);
+ break;
+ }
+ }
+ }
+
+ startTask(taskId);
+
+ if(taskIndex==0) {
+
+ // handler.sendEmptyMessage(1);
+ }
+ }
+ }
+
+
}
else{
- /* if(processingTask==null) {
+ Log.d(TAG,"ServiceDownload downloadTask size: " +downloadTasks.size());
+
+
+ new Thread() {
+
+ @Override
+ public void run() {
+ List tmp = LitePal.findAll(DownloadTask.class);
+
+ if (downloadTasks.size() == 0) {
+ taskIndex = 0;
+ for (DownloadTask dt : tmp) {
+ startNewTask(dt);
+ }
+
+ }else{
+
+ for (DownloadTask dt : tmp) {
+ boolean exist = false;
+ for(DownloadTask t: downloadTasks){
+ if(t.getId() == dt.getId()){
+ exist =true;
+ break;
+ }
+ }
+ if(!exist){
+ startNewTask(dt);
+ }
+
+ }
+
+ }
+ if (taskIndex == 0) {
+ startTask();
+ // handler.sendEmptyMessage(1);
+ }
+ }
+ }.start();
+
+
+
+
+ /*
+ if(processingTask==null) {
startTask();
}*/
}
- Log.d(TAG,"test service onHandleIntent...over");
+ Log.d(TAG,"ServiceDownload test service onHandleIntent...over");
}
+
+
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
- if(msg.what ==1){
+ /* if(msg.what ==1){
startTask();
- }else if(msg.what==2){
+ }else*/
+ if(msg.what==2){
+ int tIndex = msg.getData().getInt("tIndex");
+
+ if(tIndex>=downloadTasks.size()) {
+ return;
+ }
+ int taskId = downloadTasks.get(tIndex).getId();
+ /* if( downloadTasks.get(taskId).getDownSatus() == DownloadTask.DownStatus.等待下载){
+ return;
+ }
if(tasksMap.get(processingTask.getId())==null){
return;
}
+ */
+
+ if(tasksMap.get(taskId)==null){
+ return;
+ }
+
Log.d(TAG,String.format("%s start new chapt download---- taskId :%s, chapter count %s,chaptIndex %s",TAG
, processingTask.getId(),
tasksMap.get(processingTask.getId()).size(),chaptIndex ));
-
- Intent broadcastIntent = new Intent();
- broadcastIntent.setAction("ServiceDownload.ChapterContent.finished");
- broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
- broadcastIntent.putExtra("progress", processingTask.getFinishedChpats());
- broadcastIntent.putExtra("novelId", processingTask.getNovelId());
- sendBroadcast(broadcastIntent);
+ // if(taskIndex==tIndex+1){
- if( tasksMap.get(processingTask.getId()).size()-1 > chaptIndex){
- chaptIndex++;
+ Intent broadcastIntent = new Intent();
+ broadcastIntent.setAction("ServiceDownload.ChapterContent.finished");
+ broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
+ broadcastIntent.putExtra("progress", processingTask.getFinishedChpats()>processingTask.getTotalChapts() ?processingTask.getTotalChapts():processingTask.getFinishedChpats());
+ broadcastIntent.putExtra("novelId", processingTask.getNovelId());
+ broadcastIntent.putExtra("taskId", processingTask.getId());
+ sendBroadcast(broadcastIntent);
+
+ // }
+
+ if( tasksMap.get(taskId).size()-1 > chaptIndex){
+ if( downloadTasks.get(tIndex).getDownSatus() == DownloadTask.DownStatus.正在下载) {
+ chaptIndex++;
+ }else{
+ return;
+ }
+
}else{
Log.d(TAG,String.format("%s task done ---- taskId :%s, chapter count %s,chaptIndex %s",TAG , processingTask.getId(),
tasksMap.get(processingTask.getId()).size(),chaptIndex ));
//章节全部处理完毕了
- processingTask.setStatus(1);
- processingTask.update(processingTask.getId());
- tasksMap.remove(processingTask.getId()); //会不会线程冲突?
+ if(taskId == processingTask.getId()) {
+ int abc = 1;
+ abc++;
+ if(tasksMap.get(taskId).size() == tasksMapDone.get(taskId).size()) {
+ processingTask.setStatus(1);
+ processingTask.update(processingTask.getId());
+ // tasksMap.remove(processingTask.getId()); //会不会线程冲突?
+ }
- startTask();
+
+ }
+ //startTask(); //auto start next task
+ return;
}
- doDownloadContent();
+ doDownloadContent(tIndex,chaptIndex);
}
}
@@ -176,22 +318,67 @@ public class ServiceDownload extends IntentService {
};
+ private void stopTask(int taskId) {
+ if(processingTask==null || processingTask.getId()==taskId) {
+ //startTask();//to start next
+ }
+ }
+
+ /**
+ * 启动指定task
+ * @param taskId
+ */
+ private void startTask(int taskId) {
+ if ( downloadTasks.size()==0){
+ return;
+ }
+ if(processingTask!=null) {
+ processingTask.update(processingTask.getId());
+ }
+ taskIndex=0;
+ for(DownloadTask task : downloadTasks) {
+ if(task.getId()==taskId) {
+ processingTask = task;
+ break;
+ }
+ taskIndex++;
+ }
+
+ processingTask.setDownSatus(DownloadTask.DownStatus.正在下载);
+ chaptIndex=0;
+ doDownloadContent(taskIndex,chaptIndex);
+ }
+
+ /**
+ * auto next task
+ */
private void startTask() {
-
+ if ( downloadTasks.size()==0){
+ return;
+ }
if(processingTask!=null) {
processingTask.update(processingTask.getId());
}
+ Log.d(TAG,"ServiceDownload start task to download,index " +taskIndex);
+
if(downloadTasks.size() <=taskIndex){
+ taskIndex=0;
processingTask =null;
- Log.d(TAG,"No task to download.");
- return;
+ // Log.d(TAG,"No task to download.");
+ // return;
}
processingTask = downloadTasks.get(taskIndex);
+ if(processingTask.getDownSatus()== DownloadTask.DownStatus.等待下载){
+ taskIndex++;
+ startTask();
+ return;
+ }
+ processingTask.setDownSatus(DownloadTask.DownStatus.正在下载);
chaptIndex=0;
- doDownloadContent();
+ doDownloadContent(taskIndex,chaptIndex);
if(taskIndex < downloadTasks.size()-1){
taskIndex++;
}
@@ -199,16 +386,20 @@ public class ServiceDownload extends IntentService {
}
- void doDownloadContent(){
-
- Log.d(TAG, String.format("ServiceDowload--- taskId: %s ",processingTask.getId()));
+ void doDownloadContent(int taskIndex,int chaptIndex){
+ Message mg = Message.obtain();
+ mg.what =2;
+ Bundle bundleData = new Bundle();
+ bundleData.putInt("tIndex", taskIndex);
+ mg.setData(bundleData);
+ Log.d(TAG, String.format("ServiceDownload--- taskId: %s ",processingTask.getId()));
List chps = tasksMap.get(processingTask.getId());
- if(chps!=null && chps.size()>0) {
+ if(chps!=null && chps.size()>0 && chps.size() >chaptIndex) {
Chapter chapter = chps.get(chaptIndex);
if (TextUtils.isEmpty(chapter.getChapterPath())) {
try {
- ServiceDownload(chapter);
+ ServiceDownload(taskIndex,chapter);
} catch (JSONException e) {
e.printStackTrace();
} catch (InterruptedException e) {
@@ -218,19 +409,19 @@ public class ServiceDownload extends IntentService {
}
} else {
- handler.sendEmptyMessage(2);
+ handler.sendMessage(mg);
}
}else{
- handler.sendEmptyMessage(2);
+ handler.sendMessage(mg);
}
}
- void startNewTask(int taskId){
+ void startNewTask(DownloadTask dt){
+
- DownloadTask dt = LitePal.find(DownloadTask.class,taskId);
if(dt!=null){
- List chps = Chapter.getUnCachedChapters(dt.getNovelId(),dt.getDomain() );
+ List chps = Chapter.getUnCachedChapters(dt.getId());
if(chps==null || chps.size()==0){
return;
}
@@ -243,16 +434,16 @@ public class ServiceDownload extends IntentService {
downloadTasks.add(dt);
- for(DownloadTask tmp: downloadTasks){
+ /* for(DownloadTask tmp: downloadTasks){
Log.d(TAG, String.format("test service task list : %s",tmp.getId()));
- }
+ }*/
tasksMap.put(dt.getId(), chps);
- if(taskIndex==0) {
+ /* if(taskIndex==0) {
startTask();
// handler.sendEmptyMessage(1);
- }
+ }*/
}
}
/*
@@ -268,21 +459,27 @@ public class ServiceDownload extends IntentService {
*/
}
- private void ServiceDownload( Chapter chapter ) throws JSONException, InterruptedException {
+ private void ServiceDownload(int taskIndex, Chapter chapter ) throws JSONException, InterruptedException {
+ int taskID= downloadTasks.get(taskIndex).getId() ;
int msg =2;
-
+ Message mg = Message.obtain();
+ mg.what =msg;
+ Bundle bundleData = new Bundle();
+ bundleData.putInt("tIndex", taskIndex);
+ mg.setData(bundleData);
String url = chapter.getChapterUrl();
if( TextUtils.isEmpty( url)){
- handler.sendEmptyMessage(msg);
+ // handler.sendEmptyMessage(msg);
+ handler.sendMessage(mg);
return ;
}
long startTime= new Date().getTime();
- Log.d(TAG,String.format("ServiceDowload----start download %s from %s", chapter.getChapterName() ,url ));
+ Log.d(TAG,String.format("ServiceDownload----start download %s from %s", chapter.getChapterName() ,url ));
- // Log.d( "ServiceDowload",String.format("ServiceDowload isDownloadChapt: %s",isDownloadChapt));
+ // Log.d( "ServiceDownload",String.format("ServiceDownload isDownloadChapt: %s",isDownloadChapt));
JSONObject siteJson = new JSONObject();
siteJson.put("chapterContentRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentRegex());
siteJson.put("chapterContentDumpRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentDumpRegex());
@@ -290,10 +487,10 @@ public class ServiceDownload extends IntentService {
HttpMethods.getOkClient().newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
+ handler.sendMessage(mg);
+ // handler.sendEmptyMessage(msg);
- handler.sendEmptyMessage(msg);
-
- // Log.d( "ServiceDowload",String.format("ServiceDowload fail, isDownloadChapt: %s",isDownloadChapt));
+ // Log.d( "ServiceDownload",String.format("ServiceDownload fail, isDownloadChapt: %s",isDownloadChapt));
e.printStackTrace();
// throw new RuntimeException("Error during writing " + fileChapterName( index));
}
@@ -303,12 +500,13 @@ public class ServiceDownload extends IntentService {
ResponseBody body = response.body();
if (body != null ) {
if(response.code()!=200){
- Log.d(TAG, "ServiceDowload----network failure returnCode " + response.code());
+ Log.d(TAG, "ServiceDownload----network failure returnCode " + response.code());
// setDownloadFlag(true);
// chaptDownStatus.put(index, BookUtil.DownloadStatus.failure);
- // Log.d( "ServiceDowload",String.format("ServiceDowload error %s ,isDownloadChapt: %s", response.code(),isDownloadChapt));
- handler.sendEmptyMessage(msg);
- return;
+ // Log.d( "ServiceDownload",String.format("ServiceDownload error %s ,isDownloadChapt: %s", response.code(),isDownloadChapt));
+ // handler.sendEmptyMessage(msg);
+ handler.sendMessage(mg);
+ return;
}
try {
@@ -322,7 +520,7 @@ public class ServiceDownload extends IntentService {
final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(chapter)), "utf-8");//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小
writer.write(buf);
writer.close();
- Log.d( "ServiceDowload",String.format("ServiceDowload file created: %s", file.getPath()));
+ Log.d( "ServiceDownload",String.format("ServiceDownload file created: %s", file.getPath()));
processingTask.setFinishedChpats(processingTask.getFinishedChpats()+1);
processingTask.update(processingTask.getId());
Thread.sleep(siteRuleMap.get(chapter.getNovelId()).getMiniInterval4AccessChapter());
@@ -340,11 +538,16 @@ public class ServiceDownload extends IntentService {
chapter.setChapterPath(fileChapterName(chapter));
chapter.update(chapter.getId());
- handler.sendEmptyMessage(msg);
+ if(! tasksMapDone.containsKey(taskID)){
+ tasksMapDone.put(taskID,new ArrayList());
+ }
+ tasksMapDone.get(taskID).add(chapter);
+
+ handler.sendMessage(mg);
//setDownloadFlag(true);
// chaptDownStatus.put(index, BookUtil.DownloadStatus.success);
- Log.d(TAG,String.format("ServiceDowload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() -startTime ,chapter.getChapterPath() ));
+ Log.d(TAG,String.format("ServiceDownload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() -startTime ,chapter.getChapterPath() ));
}
}
@@ -370,10 +573,10 @@ public class ServiceDownload extends IntentService {
return;
}
long startTime = new Date().getTime();
- Log.d(TAG, String.format("ServiceDowload----start download %s from %s", chapter.getChapterName(), url));
+ Log.d(TAG, String.format("ServiceDownload----start download %s from %s", chapter.getChapterName(), url));
- // Log.d( "ServiceDowload",String.format("ServiceDowload isDownloadChapt: %s",isDownloadChapt));
+ // Log.d( "ServiceDownload",String.format("ServiceDownload isDownloadChapt: %s",isDownloadChapt));
JSONObject siteJson = new JSONObject();
siteJson.put("chapterContentRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentRegex());
siteJson.put("chapterContentDumpRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentDumpRegex());
@@ -382,10 +585,10 @@ public class ServiceDownload extends IntentService {
ResponseBody body = response.body();
if (body != null) {
if (response.code() != 200) {
- Log.d(TAG, "ServiceDowload----network failure returnCode " + response.code());
+ Log.d(TAG, "ServiceDownload----network failure returnCode " + response.code());
// setDownloadFlag(true);
// chaptDownStatus.put(index, BookUtil.DownloadStatus.failure);
- // Log.d( "ServiceDowload",String.format("ServiceDowload error %s ,isDownloadChapt: %s", response.code(),isDownloadChapt));
+ // Log.d( "ServiceDownload",String.format("ServiceDownload error %s ,isDownloadChapt: %s", response.code(),isDownloadChapt));
handler.sendEmptyMessage(msg);
return;
}
@@ -401,7 +604,7 @@ public class ServiceDownload extends IntentService {
final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(chapter)), "utf-8");//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小
writer.write(buf);
writer.close();
- Log.d("ServiceDowload", String.format("ServiceDowload file created: %s", file.getPath()));
+ Log.d("ServiceDownload", String.format("ServiceDownload file created: %s", file.getPath()));
processingTask.setFinishedChpats(processingTask.getFinishedChpats() + 1);
processingTask.update(processingTask.getId());
Thread.sleep(siteRuleMap.get(chapter.getNovelId()).getMiniInterval4AccessChapter());
@@ -422,7 +625,7 @@ public class ServiceDownload extends IntentService {
//setDownloadFlag(true);
// chaptDownStatus.put(index, BookUtil.DownloadStatus.success);
- Log.d(TAG, String.format("ServiceDowload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() - startTime, chapter.getChapterPath()));
+ Log.d(TAG, String.format("ServiceDownload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() - startTime, chapter.getChapterPath()));
}
diff --git a/zhuike/src/main/java/com/novelbook/android/service/ServiceDownloadIntent.java b/zhuike/src/main/java/com/novelbook/android/service/ServiceDownloadIntent.java
new file mode 100644
index 0000000..d64a61c
--- /dev/null
+++ b/zhuike/src/main/java/com/novelbook/android/service/ServiceDownloadIntent.java
@@ -0,0 +1,500 @@
+package com.novelbook.android.service;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Message;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.novelbook.android.db.Chapter;
+import com.novelbook.android.db.DownloadTask;
+import com.novelbook.android.db.SiteRule;
+import com.novelbook.android.netutils.HttpMethods;
+import com.novelbook.android.utils.BookUtil;
+import com.novelbook.android.utils.NovelParseUtil;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.litepal.LitePal;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.Request;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+
+
+public class ServiceDownloadIntent extends IntentService {
+ private static final String TAG ="ServiceDownload" ;
+
+ private final String storagePath = BookUtil.storagePath;
+ private final String cachedPath = BookUtil.cachedPath;
+ private final String chapterPath = BookUtil.chapterPath;
+
+ public final String EXTR_TASKID ="taskId";
+ public final String EXTR_OFFSET ="offset"; //多线程下载,每个线程取章节偏移数量
+
+
+
+
+ // public ServiceDownload(String name) {
+ // super(name);
+ // }
+ public ServiceDownloadIntent() {
+ super("ServiceDownload");
+ }
+
+ private Map siteRuleMap = new HashMap() ; // key = novelId
+ private DownloadTask processingTask ;
+ private int taskIndex=0;
+ private int chaptIndex=0;
+
+ private Map> tasksMap = new ConcurrentHashMap>();// key = taskId
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ Log.d(TAG,"test service onCreate...");
+
+ /*
+ downloadTasks =LitePal.where("status = ?","0").find(DownloadTask.class);
+ for(DownloadTask dt :downloadTasks){
+ List chps =Chapter.getUnCachedChapters(dt.getNovelId(),dt.getDomain());
+ if(chps.size()>0) {
+ SiteRule sr = SiteRule.getSiteRuleByDomain(dt.getDomain());
+ siteRuleMap.put(dt.getNovelId(), sr);
+ tasksMap.put(dt.getId(), chps);
+ }
+ }
+
+ for(DownloadTask tmp: downloadTasks){
+ Log.d(TAG, String.format("test service task list : %s",tmp.getId()));
+ }
+ */
+
+
+ }
+ @Override
+ public void onStart(Intent intent, int startId) {
+ super.onStart(intent, startId);
+ Log.d(TAG,"test service onStart");
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Log.d(TAG,"test service onStartCommand");
+ return super.onStartCommand(intent, flags, startId);
+
+ }
+
+ @Override
+ public void onDestroy() {
+ Log.d(TAG,"test service onDestroy");
+ super.onDestroy();
+ }
+
+
+
+ private List downloadTasks = new ArrayList();
+
+ int cancelId =0;
+ @Override
+ protected void onHandleIntent( Intent intent) {
+ Log.d(TAG,"test service onHandleIntent...begin");
+
+ String key ="taskId";
+ int taskId =0;
+
+ if(intent.hasExtra(key)){
+ taskId= intent.getExtras().getInt(key);
+ DownloadTask dt = LitePal.find(DownloadTask.class,taskId);
+
+ if(intent.hasExtra("start")){
+ if(!intent.getBooleanExtra("start",true)){
+ cancelId = taskId;
+ stopTask(taskId);
+ }else{
+ startNewTask(dt);
+ }
+ }
+
+
+ }
+ else{
+ if(downloadTasks.size()==0) {
+ List tmp = LitePal.findAll(DownloadTask.class);
+ taskIndex=0;
+ for(DownloadTask dt :tmp) {
+ startNewTask(dt);
+ }
+
+
+ }
+
+
+ /*
+ if(processingTask==null) {
+ startTask();
+ }*/
+ }
+ Log.d(TAG,"test service onHandleIntent...over");
+ }
+
+ private void stopTask(int taskId) {
+ for(DownloadTask dt : downloadTasks){
+ if(dt.getId() == taskId){
+ dt.setDownSatus(DownloadTask.DownStatus.等待下载);
+ }
+ }
+
+ startTask();
+ }
+
+ Handler handler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ if(msg.what ==1){
+ startTask();
+ }else if(msg.what==2){
+
+ if( downloadTasks.get(taskIndex).getDownSatus() == DownloadTask.DownStatus.等待下载){
+ return;
+ }
+ if(tasksMap.get(processingTask.getId())==null){
+ return;
+ }
+ Log.d(TAG,String.format("%s start new chapt download---- taskId :%s, chapter count %s,chaptIndex %s",TAG
+ , processingTask.getId(),
+ tasksMap.get(processingTask.getId()).size(),chaptIndex ));
+
+
+ Intent broadcastIntent = new Intent();
+ broadcastIntent.setAction("ServiceDownload.ChapterContent.finished");
+ broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
+ broadcastIntent.putExtra("progress", processingTask.getFinishedChpats());
+ broadcastIntent.putExtra("novelId", processingTask.getNovelId());
+ broadcastIntent.putExtra("taskId", processingTask.getId());
+ sendBroadcast(broadcastIntent);
+
+
+ if( tasksMap.get(processingTask.getId()).size()-1 > chaptIndex){
+
+ chaptIndex++;
+
+ }else{
+ Log.d(TAG,String.format("%s task done ---- taskId :%s, chapter count %s,chaptIndex %s",TAG , processingTask.getId(),
+ tasksMap.get(processingTask.getId()).size(),chaptIndex ));
+ //章节全部处理完毕了
+ processingTask.setStatus(1);
+ processingTask.update(processingTask.getId());
+
+ tasksMap.remove(processingTask.getId()); //会不会线程冲突?
+
+ startTask();
+ }
+
+ doDownloadContent();
+ }
+
+ }
+
+ };
+
+
+
+ private void startTask() {
+
+ if(processingTask!=null) {
+ processingTask.update(processingTask.getId());
+ }
+
+
+
+ if(downloadTasks.size() <=taskIndex){
+ processingTask =null;
+ Log.d(TAG,"No task to download.");
+ return;
+ }
+
+ processingTask = downloadTasks.get(taskIndex);
+ if(processingTask.getDownSatus()== DownloadTask.DownStatus.等待下载){
+ taskIndex++;
+ startTask();
+ return;
+ }
+ processingTask.setDownSatus(DownloadTask.DownStatus.正在下载);
+ chaptIndex=0;
+ doDownloadContent();
+ if(taskIndex < downloadTasks.size()-1){
+ taskIndex++;
+ }
+
+ }
+
+
+ void doDownloadContent(){
+
+ Log.d(TAG, String.format("ServiceDowload--- taskId: %s ",processingTask.getId()));
+ List chps = tasksMap.get(processingTask.getId());
+ if(chps!=null && chps.size()>0) {
+ Chapter chapter = chps.get(chaptIndex);
+
+ if (TextUtils.isEmpty(chapter.getChapterPath())) {
+ try {
+ ServiceDownload(chapter);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ // } catch (IOException e) {
+ // e.printStackTrace();
+ }
+
+ } else {
+ handler.sendEmptyMessage(2);
+ }
+ }else{
+ handler.sendEmptyMessage(2);
+ }
+ }
+
+ void startNewTask(DownloadTask dt){
+
+
+
+ if(dt!=null){
+ List chps = Chapter.getUnCachedChapters(dt.getId() );
+ if(chps==null || chps.size()==0){
+ return;
+ }
+ SiteRule siteRule = SiteRule. getSiteRuleByDomain(dt.getDomain());
+ if(siteRule==null){
+ //to do get siterule from web
+ Log.d(TAG, String.format("没找到site rule: %s",dt.getDomain()));
+ }else {
+ siteRuleMap.put(dt.getNovelId(),siteRule);
+
+ downloadTasks.add(dt);
+
+ for(DownloadTask tmp: downloadTasks){
+ Log.d(TAG, String.format("test service task list : %s",tmp.getId()));
+ }
+
+
+ tasksMap.put(dt.getId(), chps);
+ if(taskIndex==0) {
+ startTask();
+ // handler.sendEmptyMessage(1);
+ }
+ }
+ }
+ /*
+ new Thread() {
+
+ @Override
+ public void run() {
+
+
+
+ }
+ }.start();
+
+ */
+ }
+ private void ServiceDownload( Chapter chapter ) throws JSONException, InterruptedException {
+
+ int msg =2;
+
+ String url = chapter.getChapterUrl();
+ if( TextUtils.isEmpty( url)){
+ handler.sendEmptyMessage(msg);
+ return ;
+ }
+ long startTime= new Date().getTime();
+ Log.d(TAG,String.format("ServiceDowload----start download %s from %s", chapter.getChapterName() ,url ));
+
+
+
+ // Log.d( "ServiceDowload",String.format("ServiceDowload isDownloadChapt: %s",isDownloadChapt));
+ JSONObject siteJson = new JSONObject();
+ siteJson.put("chapterContentRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentRegex());
+ siteJson.put("chapterContentDumpRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentDumpRegex());
+ Request request = getTagRequest(url);
+ HttpMethods.getOkClient().newCall(request).enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+
+ handler.sendEmptyMessage(msg);
+
+ // Log.d( "ServiceDowload",String.format("ServiceDowload fail, isDownloadChapt: %s",isDownloadChapt));
+ e.printStackTrace();
+ // throw new RuntimeException("Error during writing " + fileChapterName( index));
+ }
+
+ @Override
+ public void onResponse(Call call, Response response){
+ ResponseBody body = response.body();
+ if (body != null ) {
+ if(response.code()!=200){
+ Log.d(TAG, "ServiceDowload----network failure returnCode " + response.code());
+ // setDownloadFlag(true);
+ // chaptDownStatus.put(index, BookUtil.DownloadStatus.failure);
+ // Log.d( "ServiceDowload",String.format("ServiceDowload error %s ,isDownloadChapt: %s", response.code(),isDownloadChapt));
+ handler.sendEmptyMessage(msg);
+ return;
+ }
+
+ try {
+ String bodyStr = body.string();
+ String title = chapter.getChapterName();
+ String chapterContent = title+ "\n" + NovelParseUtil.getChapterContent(bodyStr, siteJson);
+ char[] buf = chapterContent.toCharArray();
+ File file = new File(fileChapterName(chapter));
+ file.createNewFile();
+
+ final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(chapter)), "utf-8");//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小
+ writer.write(buf);
+ writer.close();
+ Log.d( "ServiceDowload",String.format("ServiceDowload file created: %s", file.getPath()));
+ processingTask.setFinishedChpats(processingTask.getFinishedChpats()+1);
+ processingTask.update(processingTask.getId());
+ Thread.sleep(siteRuleMap.get(chapter.getNovelId()).getMiniInterval4AccessChapter());
+ // setDownloadFlag(true);
+ } catch (IOException | JSONException | InterruptedException e) {
+ e.printStackTrace();
+ // throw new RuntimeException("Error during writing " + fileChapterName( index));
+ }
+ finally {
+ body.close();
+
+
+ // setDownloadFlag(true);
+ }
+
+ chapter.setChapterPath(fileChapterName(chapter));
+ chapter.update(chapter.getId());
+ handler.sendEmptyMessage(msg);
+
+ //setDownloadFlag(true);
+ // chaptDownStatus.put(index, BookUtil.DownloadStatus.success);
+ Log.d(TAG,String.format("ServiceDowload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() -startTime ,chapter.getChapterPath() ));
+
+ }
+ }
+ });
+
+
+ }
+
+ /**
+ * 直接
+ * @param chapter
+ * @throws JSONException
+ * @throws InterruptedException
+
+
+ private void ServiceDownload2( Chapter chapter ) throws IOException, JSONException, InterruptedException {
+
+ int msg = 2;
+
+ String url = chapter.getChapterUrl();
+ if (TextUtils.isEmpty(url)) {
+ handler.sendEmptyMessage(msg);
+ return;
+ }
+ long startTime = new Date().getTime();
+ Log.d(TAG, String.format("ServiceDowload----start download %s from %s", chapter.getChapterName(), url));
+
+
+ // Log.d( "ServiceDowload",String.format("ServiceDowload isDownloadChapt: %s",isDownloadChapt));
+ JSONObject siteJson = new JSONObject();
+ siteJson.put("chapterContentRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentRegex());
+ siteJson.put("chapterContentDumpRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentDumpRegex());
+ Request request = getTagRequest(url);
+ Response response = HttpMethods.getOkClient().newCall(request).execute();
+ ResponseBody body = response.body();
+ if (body != null) {
+ if (response.code() != 200) {
+ Log.d(TAG, "ServiceDowload----network failure returnCode " + response.code());
+ // setDownloadFlag(true);
+ // chaptDownStatus.put(index, BookUtil.DownloadStatus.failure);
+ // Log.d( "ServiceDowload",String.format("ServiceDowload error %s ,isDownloadChapt: %s", response.code(),isDownloadChapt));
+ handler.sendEmptyMessage(msg);
+ return;
+ }
+
+ try {
+ String bodyStr = body.string();
+ String title = chapter.getChapterName();
+ String chapterContent = title + "\n" + NovelParseUtil.getChapterContent(bodyStr, siteJson);
+ char[] buf = chapterContent.toCharArray();
+ File file = new File(fileChapterName(chapter));
+ file.createNewFile();
+
+ final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(chapter)), "utf-8");//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小
+ writer.write(buf);
+ writer.close();
+ Log.d("ServiceDowload", String.format("ServiceDowload file created: %s", file.getPath()));
+ processingTask.setFinishedChpats(processingTask.getFinishedChpats() + 1);
+ processingTask.update(processingTask.getId());
+ Thread.sleep(siteRuleMap.get(chapter.getNovelId()).getMiniInterval4AccessChapter());
+ // setDownloadFlag(true);
+ } catch (IOException | JSONException | InterruptedException e) {
+ e.printStackTrace();
+ // throw new RuntimeException("Error during writing " + fileChapterName( index));
+ } finally {
+ body.close();
+
+
+ // setDownloadFlag(true);
+ }
+
+ chapter.setChapterPath(fileChapterName(chapter));
+ chapter.update(chapter.getId());
+ handler.sendEmptyMessage(msg);
+
+ //setDownloadFlag(true);
+ // chaptDownStatus.put(index, BookUtil.DownloadStatus.success);
+ Log.d(TAG, String.format("ServiceDowload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() - startTime, chapter.getChapterPath()));
+
+ }
+
+
+ }
+*/
+
+ protected String fileChapterName(Chapter chapter ) {
+ return getChapterPath(chapter.getNovelId()) +chapter.getDomain()+"/"+ chapter.getIndex() ;
+
+ }
+ String getChapterPath(int novelId){
+ File file = new File(chapterPath +novelId);
+ if(!file.exists()){
+ file.mkdir();
+ }
+ return chapterPath +novelId+"/";
+ }
+
+ private Request getTagRequest(String url) {
+ return new Request.Builder()
+ .tag(processingTask.getNovelId()) //标记
+ .url(url)
+ // .header("User-Agent", "OkHttp Example")
+ .build();
+ }
+
+
+
+}
diff --git a/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java b/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java
index b1361a5..832c946 100644
--- a/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java
+++ b/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java
@@ -248,6 +248,7 @@ public class BookUtil {
file.mkdir();
}
mNovel.setDomain(mSite.getDomain());
+ mNovel.setDomainName(mSite.getName());
mNovel.setMuluUrl(mSite.getMuluUrl());
mNovel.update(mNovel.getId());
}
@@ -818,7 +819,7 @@ int muluRetryCount =0;
if (!st.getDomain().equals(mSite.getDomain())) {
//mSite = st;
mNovel.setDomain(st.getDomain());
-
+ mNovel.setDomainName(mSite.getName());
bundleData.putString("siteName", st.getName());
msg.setData(bundleData);
break;
diff --git a/zhuike/src/main/res/layout/activitycache.xml b/zhuike/src/main/res/layout/activitycache.xml
new file mode 100644
index 0000000..55aa51d
--- /dev/null
+++ b/zhuike/src/main/res/layout/activitycache.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zhuike/src/main/res/layout/fragment_shelf_botoomsheetdialog.xml b/zhuike/src/main/res/layout/fragment_shelf_botoomsheetdialog.xml
index f35dc6a..e63142c 100644
--- a/zhuike/src/main/res/layout/fragment_shelf_botoomsheetdialog.xml
+++ b/zhuike/src/main/res/layout/fragment_shelf_botoomsheetdialog.xml
@@ -17,36 +17,37 @@
tools:ignore="UnusedAttribute">
+ android:paddingStart="105dp"
+ android:paddingLeft="120dp">
+ android:orientation="vertical"
+ android:paddingStart="15dp"
+ android:paddingRight="10dp"
+ android:paddingTop="5dp">
@@ -54,21 +55,21 @@
android:id="@+id/tvAuthor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:visibility="visible"
android:text="金庸"
+ android:visibility="visible"
tools:ignore="HardcodedText" />
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/zhuike/src/main/res/mipmap-mdpi/line_height_add.png b/zhuike/src/main/res/mipmap-mdpi/line_height_add.png
new file mode 100644
index 0000000..68e907a
Binary files /dev/null and b/zhuike/src/main/res/mipmap-mdpi/line_height_add.png differ
diff --git a/zhuike/src/main/res/mipmap-mdpi/line_height_lessen.png b/zhuike/src/main/res/mipmap-mdpi/line_height_lessen.png
new file mode 100644
index 0000000..4d181f8
Binary files /dev/null and b/zhuike/src/main/res/mipmap-mdpi/line_height_lessen.png differ
diff --git a/zhuike/src/main/res/mipmap-mdpi/pause.png b/zhuike/src/main/res/mipmap-mdpi/pause.png
new file mode 100644
index 0000000..46ddfc7
Binary files /dev/null and b/zhuike/src/main/res/mipmap-mdpi/pause.png differ
diff --git a/zhuike/src/main/res/mipmap-mdpi/play.png b/zhuike/src/main/res/mipmap-mdpi/play.png
new file mode 100644
index 0000000..bab6989
Binary files /dev/null and b/zhuike/src/main/res/mipmap-mdpi/play.png differ