下载管理

This commit is contained in:
mwang 2019-05-05 23:31:19 +08:00
parent 664ff9b491
commit 3c4872a58e
19 changed files with 1409 additions and 154 deletions

View File

@ -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">
<activity android:name=".view.Activitycache"></activity>
<activity
android:name=".Activity_cate_books"
android:label="@string/title_activity_cate_books"
android:launchMode="singleTask"
android:parentActivityName=".activity_cates"
android:theme="@style/ToolBarTheme.NoActionBar" />
<activity
android:name=".Activity_Search"
android:label="@string/title_activity_cates"
android:launchMode="singleTask"
android:parentActivityName=".Main2Activity"
android:theme="@style/ToolBarTheme.NoActionBar" />
<activity
android:name=".Activity_paihangbang"
android:label="@string/title_activity_paihangbang"
android:parentActivityName=".Main2Activity"
android:theme="@style/ToolBarTheme.NoActionBar">
</activity>
android:theme="@style/ToolBarTheme.NoActionBar"></activity>
<activity
android:name=".Activity_ChgSource"
android:label="@string/title_Activity_ChgSource" />
<activity
android:name=".BookActivity"
android:label="@string/title_activity_book"
android:theme="@style/ToolBarTheme.NoActionBar" />
<activity
android:name=".ReadActivity"
android:label="@string/app_name"
android:theme="@style/ToolBarTheme.NoActionBar">
</activity>
android:theme="@style/ToolBarTheme.NoActionBar"></activity>
<activity
android:name=".Main2Activity"
android:launchMode="singleTop"
android:theme="@style/ToolBarTheme.NoActionBar">
<intent-filter>
@ -64,28 +55,26 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".FileActivity"
android:label="@string/app_name"
android:theme="@style/ToolBarTheme.NoActionBar">
</activity>
android:theme="@style/ToolBarTheme.NoActionBar"></activity>
<activity
android:name=".MarkActivity"
android:label="@string/app_name"
android:theme="@style/ToolBarTheme.NoActionBar">
</activity>
android:theme="@style/ToolBarTheme.NoActionBar"></activity>
<activity
android:name=".filechooser.FileChooserActivity"
android:label="@string/app_name"
android:theme="@style/ToolBarTheme.NoActionBar">
</activity>
<service android:name="com.novelbook.android.service.ServiceDownload" android:exported="false"/>
android:theme="@style/ToolBarTheme.NoActionBar"></activity>
<activity
android:name=".Activity_cache"
android:label="@string/title_download"
android:theme="@style/ToolBarTheme.NoActionBar"></activity>
<service
android:name=".service.ServiceDownload"
android:exported="false" />
</application>
</manifest>

View File

@ -2,7 +2,7 @@
<litepal>
<dbname value="book" ></dbname>
<version value="12" ></version>
<version value="15" ></version>
<list>
<mapping class="com.novelbook.android.db.Chapter"></mapping>

View File

@ -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<DownloadTask> 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<CacheAdapter.MyViewHolder> {
private final int EMPTY_VIEW = 1;
private final int PROGRESS_VIEW = 2;
private final int IMAGE_VIEW = 3;
private Context context;
private List<DownloadTask> mDatas = new ArrayList<DownloadTask>();
private OnItemClickLitener mOnItemClickLitener;
private int listItemID;
public CacheAdapter(Context context, List<DownloadTask> 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<DownloadTask> 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<DownloadTask> 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);
}
}

View File

@ -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<Fragment> mFragments;

View File

@ -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<DownloadTask> 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<DownloadTask> 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());

View File

@ -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() {

View File

@ -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<Chapter> getUnCachedChapters(int noveId,String domain ){
public static List<Chapter> 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<Chapter> lst = LitePal.where("novelId = ? and domain = ? " ,noveId+"",domain).find(Chapter.class);
List<Chapter> lst = LitePal.where("taskId= ? " ,taskId+"").find(Chapter.class);
List<Chapter> lstrt = new ArrayList<Chapter>();
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);
}

View File

@ -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{
初始状态,等待下载, 正在下载,排队中,下载完成
}
}

View File

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

View File

@ -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<Integer,SiteRule> siteRuleMap = new HashMap<Integer,SiteRule>() ; // key = novelId
private DownloadTask processingTask ;
@ -67,6 +71,7 @@ public class ServiceDownload extends IntentService {
private int chaptIndex=0;
private Map<Integer ,List<Chapter>> tasksMap = new ConcurrentHashMap<Integer, List<Chapter>>();// key = taskId
private Map<Integer ,List<Chapter>> tasksMapDone = new ConcurrentHashMap<Integer, List<Chapter>>();// 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<DownloadTask> downloadTasks = new ArrayList<DownloadTask>();
@Override
List<Integer> cancelId =new ArrayList<Integer>();
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<DownloadTask> 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<Chapter> 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<Chapter> chps = Chapter.getUnCachedChapters(dt.getNovelId(),dt.getDomain() );
List<Chapter> 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<Chapter>());
}
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()));
}

View File

@ -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<Integer,SiteRule> siteRuleMap = new HashMap<Integer,SiteRule>() ; // key = novelId
private DownloadTask processingTask ;
private int taskIndex=0;
private int chaptIndex=0;
private Map<Integer ,List<Chapter>> tasksMap = new ConcurrentHashMap<Integer, List<Chapter>>();// 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<Chapter> 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<DownloadTask> downloadTasks = new ArrayList<DownloadTask>();
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<DownloadTask> 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<Chapter> 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<Chapter> 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();
}
}

View File

@ -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;

View File

@ -0,0 +1,35 @@
<android.support.design.widget.CoordinatorLayout 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:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:clipToPadding="true"
tools:context=".Activity_cache">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
style="@style/barLayout">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbarHeight"
android:background="?attr/colorPrimary"
app:popupTheme="@style/ToolBarTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycleView"
style="@style/llOutside"
android:layout_marginTop="50dp"
android:divider="@color/list_item_divider"
>
</android.support.v7.widget.RecyclerView>
</android.support.design.widget.CoordinatorLayout>

View File

@ -17,36 +17,37 @@
tools:ignore="UnusedAttribute">
<LinearLayout
android:clickable="true"
android:id="@+id/llBookdetail"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@color/white"
android:layout_height="110dp"
android:layout_alignParentBottom="true"
android:paddingStart="100dp"
android:paddingLeft="120dp"
android:background="@color/white"
android:clickable="true"
android:orientation="horizontal"
>
android:paddingStart="105dp"
android:paddingLeft="120dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingStart="15dp"
android:paddingRight="10dp"
android:layout_gravity="top"
android:layout_weight="1"
android:background="@drawable/item_selector"
android:orientation="vertical">
android:orientation="vertical"
android:paddingStart="15dp"
android:paddingRight="10dp"
android:paddingTop="5dp">
<TextView
android:id="@+id/bdTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:text="射雕英雄传"
android:textColor="@color/colorPrimary"
android:textSize="16sp"
android:textStyle="bold"
android:ellipsize="marquee"
tools:ignore="HardcodedText,TextViewEdits" />
@ -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" />
<TextView
android:layout_marginTop="2dp"
android:id="@+id/txtLatestCate"
style="@style/TextViewDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lines="1"
android:ellipsize="end"
android:text=""
android:id="@+id/txtLatestCate"
style="@style/TextViewDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:ellipsize="end"
android:lines="1"
android:text=""
/>
/>
<TextView
android:id="@+id/txtLatestUpdate"
@ -89,11 +90,11 @@
<android.support.v7.widget.CardView
android:id="@+id/cardView"
android:layout_width="80dp"
android:layout_height="130dp"
android:layout_marginEnd="14dp"
android:layout_marginRight="14dp"
android:layout_height="100dp"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginEnd="14dp"
android:layout_marginRight="14dp"
android:layout_marginBottom="5dp"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="6dp"

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="80dp"
android:gravity="center"
android:background="@drawable/item_selector"
android:clickable="true"
android:paddingStart="10dp"
android:layout_weight="1">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:layout_weight="1">
<LinearLayout
android:layout_marginTop="5dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:paddingRight="10dp"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tvTitle"
style="@style/TextViewNovelTitle"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_gravity="left"
android:text="射雕英雄传"
android:layout_weight="1"
android:textColor="@color/blacktitle" />
<TextView
android:id="@+id/tvStatus"
android:layout_marginLeft="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:textSize="12sp"
android:text="未知"
android:textColor="@color/grey" />
</LinearLayout>
<LinearLayout
android:layout_marginTop="5dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="10dp"
>
<TextView
android:id="@+id/tvSource"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="-/-"
android:layout_weight="1"
android:textSize="12sp"
android:textColor="@color/blacktitle" />
<TextView
android:id="@+id/tvProgress"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:textSize="12sp"
android:gravity="right"
android:layout_marginStart="50dp"
android:text="未知"
android:textColor="@color/grey" />
</LinearLayout>
<ProgressBar android:id="@+id/barProgress"
android:layout_width="fill_parent"
android:layout_height="8dp"
android:max="100"
android:paddingTop="5dp"
style="@android:style/Widget.ProgressBar.Horizontal"
/>
</LinearLayout>
<ImageView
android:clickable="true"
android:id="@+id/imgStart"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_margin="10dp"
android:src="@mipmap/play"
/>
</LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 B