2019-04-02 17:41:53 +08:00
package com.novelbook.android.utils ;
2019-04-05 23:59:31 +08:00
import android.app.ProgressDialog ;
2019-04-02 17:41:53 +08:00
import android.content.ContentValues ;
2019-04-05 23:59:31 +08:00
import android.content.Context ;
2019-04-02 17:41:53 +08:00
2019-04-18 17:19:42 +08:00
import android.os.AsyncTask ;
2019-04-05 23:59:31 +08:00
import android.os.Handler ;
import android.os.Message ;
2019-04-02 17:41:53 +08:00
import android.text.TextUtils ;
import android.util.Log ;
2019-04-05 23:59:31 +08:00
import android.widget.Toast ;
2019-04-02 17:41:53 +08:00
2019-04-05 23:59:31 +08:00
import com.google.gson.Gson ;
import com.novelbook.android.MyApp ;
2019-04-02 17:41:53 +08:00
import com.novelbook.android.bean.Cache ;
2019-04-05 23:59:31 +08:00
import com.novelbook.android.bean.NovelSites ;
import com.novelbook.android.bean.Site ;
import com.novelbook.android.db.SiteRule ;
2019-04-03 16:21:00 +08:00
import com.novelbook.android.db.Chapter ;
import com.novelbook.android.db.Novel ;
2019-04-05 23:59:31 +08:00
import com.novelbook.android.netsubscribe.BookSubscribe ;
2019-04-03 18:09:00 +08:00
import com.novelbook.android.netutils.HttpMethods ;
2019-04-20 00:26:49 +08:00
import com.novelbook.android.netutils.NetUtil ;
2019-04-05 23:59:31 +08:00
import com.novelbook.android.netutils.OnSuccessAndFaultListener ;
import com.novelbook.android.netutils.OnSuccessAndFaultSub ;
2019-04-02 17:41:53 +08:00
2019-04-03 18:09:00 +08:00
import org.json.JSONException ;
import org.json.JSONObject ;
2019-04-02 17:41:53 +08:00
import org.litepal.LitePal ;
import java.io.File ;
import java.io.FileInputStream ;
import java.io.FileOutputStream ;
import java.io.IOException ;
import java.io.InputStreamReader ;
import java.io.OutputStreamWriter ;
import java.lang.ref.WeakReference ;
import java.util.ArrayList ;
2019-04-05 23:59:31 +08:00
import java.util.Date ;
2019-04-02 17:41:53 +08:00
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
2019-04-05 23:59:31 +08:00
import okhttp3.Call ;
import okhttp3.Callback ;
2019-04-03 18:09:00 +08:00
import okhttp3.Request ;
import okhttp3.Response ;
2019-04-05 23:59:31 +08:00
import okhttp3.ResponseBody ;
2019-04-03 18:09:00 +08:00
2019-04-02 17:41:53 +08:00
public class BookUtil {
public static final String TAG = " BookUtil " ;
2019-04-08 23:16:20 +08:00
public static final String storagePath = FileUtils . getDiskCacheDir ( MyApp . applicationContext ) ; //Environment.getExternalStorageDirectory() + "/zhuike";
public static final String cachedPath = storagePath + " /cache/ " ;
public static final String chapterPath = storagePath + " /chapter/ " ;
2019-04-02 17:41:53 +08:00
private static final String charachterType = " utf-8 " ; //"UTF-16LE";
2019-04-05 23:59:31 +08:00
private Context mContext ;
private ProgressDialog progressDialog ;
private MuluStatus mMuluStatus ; //目录是否下载完成
private Gson gson = new Gson ( ) ;
public void setContext ( Context context ) {
this . mContext = context ;
}
2019-04-14 23:17:31 +08:00
public boolean isReadingCatalogs ( ) {
return mMuluStatus = = MuluStatus . isDownloading ;
}
2019-04-02 17:41:53 +08:00
//存储的字符数
public static final int cachedSize = 30000 ;
// protected final ArrayList<WeakReference<char[]>> myArray = new ArrayList<>();
public static final String lineBreakChar = " \ n " ;
protected final ArrayList < Cache > myArray = new ArrayList < > ( ) ;
//目录
2019-04-03 18:09:00 +08:00
private List < Chapter > mChapters = new ArrayList < > ( ) ;
2019-04-05 23:59:31 +08:00
//当前章节
// private Chapter mCurrentChapter;
2019-04-03 18:09:00 +08:00
public List < Chapter > getChapters ( ) {
return mChapters ;
}
public void setChapters ( List < Chapter > chapters ) {
this . mChapters = chapters ;
}
2019-04-02 17:41:53 +08:00
private String m_strCharsetName ;
private String bookName ;
private String bookPath ;
public void setBookLen ( long bookLen ) {
this . bookLen = bookLen ;
}
private long bookLen ;
private long position ;
2019-04-03 18:09:00 +08:00
private Novel mNovel ;
2019-04-05 23:59:31 +08:00
public void setNovel ( Novel novel ) {
this . mNovel = novel ;
}
2019-04-14 23:17:31 +08:00
public Novel getNovel ( ) {
return mNovel ;
}
2019-04-05 23:59:31 +08:00
//当前目录网站列表
private NovelSites mNovelSites ;
//当前目录网站
private Site mSite ;
private SiteRule mSiteRule ;
2019-04-16 23:11:00 +08:00
2019-04-26 23:33:17 +08:00
private Map < Integer , Cache > chaptCache = new HashMap < Integer , Cache > ( ) ;
private Map < Integer , DownloadStatus > chaptDownStatus = new HashMap < Integer , DownloadStatus > ( ) ;
DownloadStatus downloadStatus = DownloadStatus . notStart ;
2019-04-18 17:19:42 +08:00
public NovelSites getmNovelSites ( ) {
return mNovelSites ;
}
2019-04-23 22:45:08 +08:00
public synchronized void openBook ( Novel novel , long chapter ) throws IOException , InterruptedException {
2019-04-16 23:11:00 +08:00
this . mNovel = novel ;
//如果当前缓存不是要打开的书本就缓存书本同时删除缓存
//TODO 构建新的缓存策略, 几个选项, 1: 每本书一个缓存 2: 控制缓存总大小, 超过限制删除旧缓存 3: 网络小说的缓存
boolean isLocalImport = novel . isLocalBook ( ) ;
boolean isOnShelf = isLocalImport | | novel . isOnShelf ( ) ;
boolean isLoadChaptsFromRemote = ! isLocalImport ; // && !novel.isFinished() ; //是否从目标网站下载目录
// showProgressDialog();
if ( isLocalImport ) {
mChapters = LitePal . where ( " novelId=? " , mNovel . getId ( ) + " " ) . find ( Chapter . class ) ;
for ( Chapter c : mChapters ) {
Log . d ( TAG , String . format ( " bookchapter :%s,fileName :%s, chapter Size %s " , c . getChapterName ( ) , c . getChapterPath ( ) , c . getLength ( ) ) ) ;
}
chaptCache = new HashMap < Integer , Cache > ( ) ;
if ( mChapters . isEmpty ( ) ) { //1. 首次打开 本地导入的书
if ( bookPath = = null | | ! bookPath . equals ( mNovel . getNovelPath ( ) ) ) {
2019-04-26 23:33:17 +08:00
cleanCacheFile ( ) ;
2019-04-16 23:11:00 +08:00
this . bookPath = mNovel . getNovelPath ( ) ;
bookName = FileUtils . getFileName ( bookPath ) ;
cacheBook ( ) ;
}
}
} else { //读取目录列表
2019-04-23 22:45:08 +08:00
Log . d ( TAG , String . format ( " prepare book %s open chapter %s in background.... mMuluStatus %s, mSiteRule %s,thread %s " , mNovel . getName ( ) , chapter , mMuluStatus , mSiteRule , Thread . currentThread ( ) . getName ( ) ) ) ;
File file = new File ( fileChapterName ( ( int ) chapter ) ) ;
if ( file . exists ( ) ) {
Log . d ( TAG , String . format ( " prepare book open chapter file %s, exist,not waiting more...to open file... " , fileChapterName ( ( int ) chapter ) ) ) ;
return ;
}
2019-04-16 23:11:00 +08:00
MuluStatus m = mMuluStatus ;
// Log.d(TAG,String.format("mulu on Site %s download status %s",mSite.getDomain(),mMuluStatus));
Log . d ( TAG , String . format ( " prepare book %s open book in background.... mMuluStatus %s, mSiteRule %s,thread %s " , mNovel . getName ( ) , mMuluStatus , mSiteRule , Thread . currentThread ( ) . getName ( ) ) ) ;
2019-04-20 00:26:49 +08:00
int sleptTime = 0 ;
2019-04-16 23:11:00 +08:00
while ( mSiteRule = = null | | mMuluStatus = = null | | mMuluStatus = = MuluStatus . isDownloading ) {
2019-04-20 00:26:49 +08:00
sleptTime + + ;
2019-04-23 22:45:08 +08:00
if ( sleptTime > 400 | | sleptTime > 30 & & ! NetUtil . isNetworkConnected ( ) ) {
2019-04-20 00:26:49 +08:00
break ;
}
2019-04-23 22:45:08 +08:00
2019-04-16 23:11:00 +08:00
Thread . sleep ( 50 ) ;
if ( mMuluStatus = = MuluStatus . failed ) {
2019-04-23 22:45:08 +08:00
Log . d ( TAG , String . format ( " prepare book %s failed ,mMuluStatus %s,msiteRule %s,slept %s " , mNovel . getName ( ) , mMuluStatus , mSiteRule , sleptTime * 50 ) ) ;
// throw new RuntimeException("读取资源失败,请检查网络");
2019-04-16 23:11:00 +08:00
}
}
2019-04-23 22:45:08 +08:00
Log . d ( TAG , String . format ( " prepare book %s waiting for mulu downloading ,mMuluStatus %s,msiteRule %s,slept %s " , mNovel . getName ( ) , mMuluStatus , mSiteRule , sleptTime * 50 ) ) ;
2019-04-16 23:11:00 +08:00
}
// dismissProgressDialog();
}
2019-04-05 23:59:31 +08:00
public void setNovelSites ( NovelSites nvs ) {
this . mNovelSites = nvs ;
2019-04-15 23:26:24 +08:00
2019-04-16 23:11:00 +08:00
Log . d ( TAG , String . format ( " prepare book %s get novel sites count %s . " , mNovel . getName ( ) , nvs . getSites ( ) . length ) ) ;
2019-04-05 23:59:31 +08:00
if ( nvs . getSites ( ) . length = = 0 ) {
2019-04-15 23:26:24 +08:00
throw new RuntimeException ( " 书本错误 code 001 " ) ; //无目标网站
// return;
2019-04-05 23:59:31 +08:00
}
mSite = nvs . getSites ( ) [ 0 ] ;
if ( nvs . getSites ( ) . length > 0 )
for ( Site site : nvs . getSites ( ) ) {
if ( site . getSelectedByDefault ( ) ) {
mSite = site ;
break ;
}
}
2019-04-06 23:04:42 +08:00
getSiteRule ( ) ;
}
private void setSiteInfo ( ) {
2019-04-05 23:59:31 +08:00
File file = new File ( getChapterPath ( ) + mSite . getDomain ( ) ) ;
if ( ! file . exists ( ) ) {
file . mkdir ( ) ;
}
2019-04-06 23:04:42 +08:00
mNovel . setDomain ( mSite . getDomain ( ) ) ;
mNovel . setMuluUrl ( mSite . getMuluUrl ( ) ) ;
2019-04-07 23:49:08 +08:00
mNovel . update ( mNovel . getId ( ) ) ;
2019-04-03 18:09:00 +08:00
}
2019-04-06 23:04:42 +08:00
public void getTargetSites ( ) {
2019-04-25 02:01:18 +08:00
Log . d ( TAG , " prepare book: getTargetSites " ) ;
2019-04-06 23:04:42 +08:00
BookSubscribe . getNovelSites ( mNovel . getNovelId ( ) , new OnSuccessAndFaultSub ( new OnSuccessAndFaultListener ( ) {
@Override
public void onSuccess ( String result ) {
//成功
try {
2019-04-16 23:11:00 +08:00
Log . d ( TAG , String . format ( " prepare book %s get target sites done.thread %s " , mNovel . getName ( ) , Thread . currentThread ( ) . getName ( ) ) ) ;
2019-04-06 23:04:42 +08:00
NovelSites nvs = ( NovelSites ) gson . fromJson ( result , NovelSites . class ) ;
//pageFactory.prepareBook(mNovel,nvs, BookActivity.this);
setNovelSites ( nvs ) ;
2019-04-15 23:26:24 +08:00
2019-04-06 23:04:42 +08:00
} catch ( Exception e ) {
2019-04-16 23:11:00 +08:00
Log . d ( TAG , String . format ( " prepare book %s get target sites fail.thread %s ,msg %s " , mNovel . getName ( ) , Thread . currentThread ( ) . getName ( ) , e . getMessage ( ) ) ) ;
Log . e ( TAG , " prepare book fail " , e ) ;
2019-04-06 23:04:42 +08:00
e . printStackTrace ( ) ;
}
2019-04-07 23:49:08 +08:00
// Toast.makeText(mContext,"getMuluInfo 请求成功 " ,Toast.LENGTH_SHORT).show();
2019-04-06 23:04:42 +08:00
}
@Override
public void onFault ( String errorMsg ) {
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book %s get target sites fail.thread %s ,msg %s " , mNovel . getName ( ) , Thread . currentThread ( ) . getName ( ) , errorMsg ) ) ;
2019-04-06 23:04:42 +08:00
//失败
2019-04-07 23:49:08 +08:00
// Toast.makeText(mContext,"getMuluInfo 请求失败"+errorMsg,Toast.LENGTH_SHORT).show();
2019-04-06 23:04:42 +08:00
}
2019-04-07 23:49:08 +08:00
} , null ) ) ;
2019-04-06 23:04:42 +08:00
}
2019-04-05 23:59:31 +08:00
private void getSiteRule ( ) {
mSiteRule = null ;
BookSubscribe . getSiteRule ( mSite . getDomain ( ) , new OnSuccessAndFaultSub ( new OnSuccessAndFaultListener ( ) {
@Override
public void onSuccess ( String result ) {
2019-04-28 22:56:27 +08:00
Log . d ( TAG , " prepare book siteRule: " + result ) ;
2019-04-05 23:59:31 +08:00
//成功
2019-04-28 22:56:27 +08:00
SiteRule sr = new SiteRule ( ) ;
try {
sr = ( SiteRule ) gson . fromJson ( result , SiteRule . class ) ;
} catch ( Exception e ) {
Log . e ( TAG , " prepare book error on gson: " , e ) ;
}
2019-04-05 23:59:31 +08:00
List < SiteRule > srs = LitePal . where ( " domain=? " , sr . getDomain ( ) ) . limit ( 1 ) . find ( SiteRule . class ) ;
long id = srs . size ( ) = = 1 ? srs . get ( 0 ) . getId ( ) : 0 ;
if ( id > 0 ) {
sr . update ( id ) ;
// mSiteRule =LitePal.find(SiteRule.class,id);
} else
{
sr . save ( ) ;
}
mSiteRule = sr ;
2019-04-06 23:04:42 +08:00
setSiteInfo ( ) ;
2019-04-28 22:56:27 +08:00
Log . d ( TAG , String . format ( " prepare book %s 目录正则表达式下载完成,开始读章节信息. muluRegex size %s, thread %s " , mNovel . getName ( ) , mSiteRule . getChapterUrlRegexOnMulu ( ) . length , Thread . currentThread ( ) . getName ( ) ) ) ;
2019-04-15 23:26:24 +08:00
2019-04-10 22:19:06 +08:00
Log . d ( TAG , String . format ( " 目录正则表达式下载完成,开始读取章节信息 " ) ) ;
2019-04-28 22:56:27 +08:00
if ( mSiteRule . getChapterUrlRegexOnMulu ( ) . length > 0 ) {
mMuluStatus = MuluStatus . isDownloading ;
long startTime = new Date ( ) . getTime ( ) ;
Log . d ( TAG , String . format ( " prepare book loadChapts----start download %s,maxAge %s, 目录 from %s " , mNovel . getName ( ) , mNovel . getMaxAge ( ) , mSite . getMuluUrl ( ) ) ) ;
new Thread ( ) {
@Override
public void run ( ) {
Log . d ( TAG , " changing Source: to get site rule " ) ;
String [ ] chaps = new String [ 0 ] ;
try {
JSONObject siteJson = new JSONObject ( result ) ;
chaps = NovelParseUtil . getChapters ( mSite . getMuluUrl ( ) , siteJson ) ;
if ( chaps ! = null )
for ( String s : chaps ) {
Log . d ( TAG , " prepare book readChaptersAsync: chapt: " + s ) ;
}
2019-04-05 23:59:31 +08:00
2019-04-28 22:56:27 +08:00
} catch ( JSONException e ) {
Log . e ( TAG , " prepare book error on parese : " , e ) ;
}
2019-04-05 23:59:31 +08:00
2019-04-28 22:56:27 +08:00
if ( chaps = = null | | chaps . length = = 0 ) {
readChaptersAsync ( ) ;
} else
{
Log . d ( TAG , String . format ( " prepare book loadChapts----end download %s 目录, 目录数量 %s, cost %s " , mNovel . getName ( ) , mChapters . size ( ) , new Date ( ) . getTime ( ) - startTime ) ) ;
mMuluStatus = MuluStatus . isDone ;
Log . d ( TAG , String . format ( " prepare book %s 章节信息完成. " , mNovel . getName ( ) ) ) ;
}
}
} . start ( ) ;
} else {
readChaptersAsync ( ) ;
}
2019-04-05 23:59:31 +08:00
}
@Override
public void onFault ( String errorMsg ) {
//失败
2019-04-06 23:04:42 +08:00
Log . d ( TAG , " error on get sitRule: " + errorMsg ) ;
2019-04-05 23:59:31 +08:00
}
} , mContext ) ) ;
2019-04-06 23:04:42 +08:00
/ *
if ( mSiteRule = = null & & mSite ! = null ) {
List < SiteRule > srs = LitePal . where ( " domain=? " , mSite . getDomain ( ) ) . find ( SiteRule . class ) ;
if ( srs . size ( ) > 0 ) {
mSiteRule = srs . get ( 0 ) ;
}
} * /
2019-04-05 23:59:31 +08:00
2019-04-03 18:09:00 +08:00
}
2019-04-02 17:41:53 +08:00
public void setChapterNo ( int chapterNo ) {
this . chapterNo = chapterNo ;
2019-04-15 23:26:24 +08:00
/ *
if ( chapterNo < = mChapters . size ( ) ) {
this . chapterNo = chapterNo ;
} else {
Log . d ( TAG , String . format ( " setChapterNo: wrong chapno for book %s,site %s,total chapts %s,chaptNo %s " , mNovel . getName ( ) , mNovel . getDomain ( ) , getChapters ( ) . size ( ) , chapterNo ) ) ;
}
* /
2019-04-02 17:41:53 +08:00
}
public int getChapterNo ( ) {
2019-04-15 23:26:24 +08:00
if ( chapterNo > mChapters . size ( ) ) {
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book getChapterNo ,chapterNo %s, getChapters().size() %s " , chapterNo , mChapters . size ( ) ) ) ;
2019-04-15 23:26:24 +08:00
chapterNo = 1 ;
}
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book getChapterNo ,chapterNo %s, getChapters().size() %s " , chapterNo , mChapters . size ( ) ) ) ;
2019-04-02 17:41:53 +08:00
return chapterNo ;
}
private int chapterNo ; //当前章节
public String getLineBreakChar ( ) {
return " \ n " ;
}
public BookUtil ( ) {
checkAndCreateDir ( storagePath ) ;
checkAndCreateDir ( chapterPath ) ;
checkAndCreateDir ( cachedPath ) ;
2019-04-05 23:59:31 +08:00
}
2019-04-15 23:26:24 +08:00
public boolean isBusy ( ) {
return false ;
}
2019-04-26 23:33:17 +08:00
private long tmpChaptLen = 0 ;
public void setTmpChaptLen ( long tmpChaptLen ) {
this . tmpChaptLen = tmpChaptLen ;
}
2019-04-15 23:26:24 +08:00
2019-04-18 17:19:42 +08:00
private boolean isChangeSource = false ;
private int mChangeChapId ;
private String mChangeTitle ;
public void changeSource ( String domain , int chapId , String chapTitle ) {
Log . d ( TAG , String . format ( " changing Source: target domain %s chaptId %s, chapt title %s " , domain , chapId , chapTitle ) ) ;
if ( mSite . getDomain ( ) . equals ( domain ) ) { //当前源
Log . d ( TAG , " changing Source: same site with original " + domain ) ;
return ;
}
2019-04-26 23:33:17 +08:00
this . muluRetryCount = 0 ;
this . downloadStatus = DownloadStatus . notStart ;
chaptDownStatus . clear ( ) ;
chaptCache . clear ( ) ;
2019-04-18 17:19:42 +08:00
mChangeChapId = chapId ;
mChangeTitle = chapTitle ;
for ( Site site : mNovelSites . getSites ( ) ) {
if ( site . getDomain ( ) . equals ( domain ) ) {
mSite = site ;
break ;
}
}
setSiteInfo ( ) ;
2019-04-21 10:57:20 +08:00
2019-04-18 17:19:42 +08:00
isChangeSource = true ;
mChapters . clear ( ) ;
getSiteRule ( ) ;
BookTask btsk = new BookTask ( ) ;
btsk . execute ( domain , chapId + " " , chapTitle ) ;
}
public String getSite ( ) {
return mSite ! = null ? mSite . getDomain ( ) : " " ;
}
2019-04-25 02:01:18 +08:00
public boolean chaptCached ( int num ) {
File f = new File ( fileChapterName ( num ) ) ;
return f . exists ( ) ;
}
2019-04-26 23:33:17 +08:00
2019-04-18 17:19:42 +08:00
private class BookTask extends AsyncTask < String , Void , Boolean > {
private String domain ;
private int chapId ;
private String chapTitle ;
@Override
protected void onPostExecute ( Boolean result ) {
super . onPostExecute ( result ) ;
Log . d ( " onPostExecute " , isCancelled ( ) + " " ) ;
if ( isCancelled ( ) ) {
return ;
}
if ( result ) {
Log . d ( TAG , " changing Source:successed get chapters for " + mSite . getDomain ( ) ) ;
int chId = chapterNo ;
String title = " " ;
if ( mChapters . size ( ) > = mChangeChapId & & mChapters . get ( mChangeChapId - 1 ) ! = null ) {
title = mChapters . get ( mChangeChapId - 1 ) . getChapterName ( ) ;
Log . d ( TAG , " changing Source:chapter name in new site " + title ) ;
}
if ( title . equals ( mChangeTitle ) ) {
Log . d ( TAG , " changing Source:successed find chapter by original chaptId " + mChangeChapId + " : " + mChangeTitle ) ;
chId = mChangeChapId ;
}
else {
int i = 1 ;
for ( Chapter chapter : mChapters ) {
Log . d ( TAG , " changing Source: finding chapter " + i + " : " + chapter . getChapterName ( ) ) ;
if ( chapter . getChapterName ( ) . equals ( mChangeTitle ) ) {
Log . d ( TAG , " changing Source:successed find chapter by original title " + i + " : " + mChangeTitle ) ;
chId = i ;
break ;
}
i + + ;
}
}
chId = chId < = mChapters . size ( ) ? chId : mChapters . size ( ) ;
Log . d ( TAG , " changing Source: to open chapter with new site source " + chId + " : " + mChangeTitle ) ;
pagefactory . changeChapter ( chId ) ;
Toast . makeText ( mContext , " 换源成功 " , Toast . LENGTH_LONG ) . show ( ) ;
} else {
Log . d ( TAG , " changing Source: failed " ) ;
}
}
@Override
protected Boolean doInBackground ( String . . . params ) {
domain = params [ 0 ] ;
chapId = Integer . parseInt ( params [ 1 ] ) ;
chapTitle = params [ 2 ] ;
int splet = 0 ;
while ( isChangeSource ) {
try {
Thread . sleep ( 50 ) ;
splet + + ;
Log . d ( TAG , String . format ( " changing Source slept %s,isChangeSource %s " , splet , isChangeSource ) ) ;
} catch ( InterruptedException e ) {
e . printStackTrace ( ) ;
}
}
return true ;
}
@Override
protected void onPreExecute ( ) {
super . onPreExecute ( ) ;
}
@Override
protected void onProgressUpdate ( Void . . . values ) {
super . onProgressUpdate ( values ) ;
}
}
/ * *
* 新线程换源 , handler 有问题
* @param domain
* @param chapId
* @param chapTitle
* /
public void changeSourceNewThread ( String domain , int chapId , String chapTitle ) {
Log . d ( TAG , String . format ( " changing Source: target domain %s chaptId %s, chapt title %s " , domain , chapId , chapTitle ) ) ;
if ( mSite . getDomain ( ) . equals ( domain ) ) { //当前源
Log . d ( TAG , " changing Source: same site with original " + domain ) ;
// return;
}
mChangeChapId = chapId ;
mChangeTitle = chapTitle ;
for ( Site site : mNovelSites . getSites ( ) ) {
if ( site . getDomain ( ) . equals ( domain ) ) {
mSite = site ;
break ;
}
}
setSiteInfo ( ) ;
// showProgressDialog();
isChangeSource = true ;
new Thread ( ) {
@Override
public void run ( ) {
Log . d ( TAG , " changing Source: to get site rule " ) ;
getSiteRule ( ) ;
}
} . start ( ) ;
/ *
while ( isChangeSource ) {
try {
Thread . sleep ( 50 ) ;
} catch ( InterruptedException e ) {
e . printStackTrace ( ) ;
}
}
new Thread ( ) {
@Override
public void run ( ) {
Log . d ( TAG , " changing Source: to get site rule " ) ;
getSiteRule ( ) ;
}
} . start ( ) ; * /
}
2019-04-05 23:59:31 +08:00
enum MuluStatus {
isDownloading ,
isDone ,
failed
}
2019-04-21 10:57:20 +08:00
/ * private void showProgressDialog ( String title , boolean canBreak ) {
2019-04-05 23:59:31 +08:00
if ( null = = progressDialog ) {
progressDialog = new ProgressDialog ( mContext ) ;
2019-04-18 17:19:42 +08:00
2019-04-05 23:59:31 +08:00
}
2019-04-18 17:19:42 +08:00
progressDialog . setMessage ( title ) ;
progressDialog . setCancelable ( canBreak ) ;
2019-04-05 23:59:31 +08:00
progressDialog . show ( ) ;
2019-04-07 23:49:08 +08:00
// progressDialog.show(mContext,"网络不给力","正努力加载",false,true);
2019-04-05 23:59:31 +08:00
}
private void dismissProgressDialog ( ) {
if ( null ! = progressDialog ) {
progressDialog . dismiss ( ) ;
}
2019-04-02 17:41:53 +08:00
}
2019-04-21 10:57:20 +08:00
* /
2019-04-02 17:41:53 +08:00
private void checkAndCreateDir ( String path ) {
File file = new File ( path ) ;
if ( ! file . exists ( ) ) {
file . mkdir ( ) ;
}
}
2019-04-28 22:56:27 +08:00
2019-04-05 23:59:31 +08:00
2019-04-23 22:45:08 +08:00
int muluRetryCount = 0 ;
2019-04-05 23:59:31 +08:00
void readChaptersAsync ( ) {
2019-04-26 00:31:07 +08:00
if ( mSite = = null | | mSiteRule = = null ) {
Log . d ( TAG , String . format ( " prepare book loadChapts failed---- %s ,mSite is null? %s ,mSiteRule ==null ? %s " , mNovel . getName ( ) , mSite = = null , mSiteRule = = null ) ) ;
return ;
}
2019-04-05 23:59:31 +08:00
String url = mSite . getMuluUrl ( ) ;
2019-04-28 22:56:27 +08:00
Request request = getTagRequest ( url , mNovel . getMaxAge ( ) ) ;
2019-04-05 23:59:31 +08:00
mMuluStatus = MuluStatus . isDownloading ;
long startTime = new Date ( ) . getTime ( ) ;
2019-04-28 22:56:27 +08:00
Log . d ( TAG , String . format ( " prepare book loadChapts----start download %s,maxAge %s, 目录 from %s " , mNovel . getName ( ) , mNovel . getMaxAge ( ) , url ) ) ;
2019-04-05 23:59:31 +08:00
2019-04-23 22:45:08 +08:00
/ * if ( muluRetryCount < 3 ) {
muluRetryCount + + ;
return ;
}
if ( muluRetryCount > = 3 ) {
return ;
} * /
2019-04-05 23:59:31 +08:00
2019-04-28 22:56:27 +08:00
HttpMethods . getOkClient ( ) . newCall ( request ) . enqueue ( new Callback ( ) {
2019-04-05 23:59:31 +08:00
@Override
public void onFailure ( Call call , IOException e ) {
2019-04-23 22:45:08 +08:00
// Log.d(TAG, "onFailure: " + e.getMessage());
Log . e ( TAG , " prepare book loadChapts---- failed: " , e ) ;
Log . d ( TAG , String . format ( " prepare book loadChapts---- failed %s 目录 from %s " , mNovel . getName ( ) , url ) ) ;
2019-04-10 22:19:06 +08:00
2019-04-18 17:19:42 +08:00
handler . sendEmptyMessage ( 3 ) ;
2019-04-16 23:11:00 +08:00
//TODO 如果是取消了访问,则返回
2019-04-23 22:45:08 +08:00
if ( e . toString ( ) . contains ( " closed " ) | | e . getMessage ( ) . contains ( " Canceled " ) ) {
Log . d ( TAG , String . format ( " prepare book loadChapts---- canceled %s 目录 from %s " , mNovel . getName ( ) , url ) ) ;
2019-04-18 23:34:19 +08:00
return ;
}
2019-04-23 22:45:08 +08:00
mMuluStatus = MuluStatus . failed ;
2019-04-25 02:01:18 +08:00
if ( muluRetryCount < Constants . retryCnt ) {
2019-04-23 22:45:08 +08:00
try {
Thread . sleep ( 50 ) ;
} catch ( InterruptedException e1 ) {
e1 . printStackTrace ( ) ;
}
muluRetryCount + + ;
Log . d ( TAG , String . format ( " prepare book loadChapts----failed, retrying count %s " , muluRetryCount ) ) ;
readChaptersAsync ( ) ;
}
if ( mNovelSites . getSites ( ) . length = = 1 ) { //仅有一个rule,且失败了
// mMuluStatus = MuluStatus.failed;
2019-04-18 23:34:19 +08:00
2019-04-05 23:59:31 +08:00
return ;
}
//try next site
2019-04-23 22:45:08 +08:00
for ( Site st : mNovelSites . getSites ( ) ) {
if ( ! st . getDomain ( ) . equals ( mSite . getDomain ( ) ) ) {
mSite = st ;
break ;
}
}
muluRetryCount = 0 ;
// readChaptersAsync();
getSiteRule ( ) ;
}
2019-04-05 23:59:31 +08:00
@Override
public void onResponse ( Call call , Response response ) {
ResponseBody body = response . body ( ) ;
2019-04-23 22:45:08 +08:00
2019-04-06 23:04:42 +08:00
if ( response . code ( ) ! = 200 ) {
2019-04-23 22:45:08 +08:00
Log . d ( TAG , String . format ( " prepare book loadChapts----failed, %s 目录 from %s,return code %s " , mNovel . getName ( ) , url , response . code ( ) ) ) ;
2019-04-18 17:19:42 +08:00
handler . sendEmptyMessage ( 3 ) ;
2019-04-06 23:04:42 +08:00
mMuluStatus = MuluStatus . failed ;
2019-04-25 02:01:18 +08:00
if ( muluRetryCount < Constants . retryCnt ) {
2019-04-23 22:45:08 +08:00
Log . d ( TAG , String . format ( " prepare book loadChapts----failed, response code %s retrying count %s " , response . code ( ) , muluRetryCount ) ) ;
muluRetryCount + + ;
readChaptersAsync ( ) ;
}
2019-04-06 23:04:42 +08:00
return ;
}
2019-04-23 22:45:08 +08:00
muluRetryCount = 0 ;
2019-04-05 23:59:31 +08:00
if ( body ! = null ) {
2019-04-16 23:11:00 +08:00
Log . d ( TAG , String . format ( " prepare book %s 章节信息读取成功.thread %s " , mNovel . getName ( ) , Thread . currentThread ( ) . getName ( ) ) ) ;
2019-04-05 23:59:31 +08:00
try {
String bodyStr = body . string ( ) ;
2019-04-10 22:19:06 +08:00
// Log.d(TAG, "onResponse: " +bodyStr);
// Log.d(TAG,String.format("loadChaptContent----end download %s 目录, 目录数量 %s, cost %s", mNovel.getName() , mChapters.size(), new Date().getTime() -startTime ));
// long startTime2= new Date().getTime();
2019-04-15 23:26:24 +08:00
buildChapters ( bodyStr , url ) ;
2019-04-23 22:45:08 +08:00
Log . d ( TAG , String . format ( " prepare book loadChapts----end download %s 目录, 目录数量 %s, cost %s " , mNovel . getName ( ) , mChapters . size ( ) , new Date ( ) . getTime ( ) - startTime ) ) ;
2019-04-05 23:59:31 +08:00
mMuluStatus = MuluStatus . isDone ;
2019-04-15 23:26:24 +08:00
Log . d ( TAG , String . format ( " prepare book %s 章节信息完成. " , mNovel . getName ( ) ) ) ;
2019-04-03 18:09:00 +08:00
2019-04-05 23:59:31 +08:00
} catch ( IOException e ) {
e . printStackTrace ( ) ;
} finally {
body . close ( ) ;
2019-04-18 17:19:42 +08:00
handler . sendEmptyMessage ( 3 ) ;
2019-04-05 23:59:31 +08:00
}
}
}
} ) ;
}
2019-04-15 23:26:24 +08:00
void buildChapters ( String content , String url ) {
2019-04-28 22:56:27 +08:00
Log . d ( TAG , " buildChapters: " + content ) ;
2019-04-26 00:31:07 +08:00
if ( mSite = = null | | mSiteRule = = null ) {
Log . d ( TAG , String . format ( " prepare book buildChapters failed---- %s ,mSite is null? %s ,mSiteRule ==null ? %s " , mNovel . getName ( ) , mSite = = null , mSiteRule = = null ) ) ;
return ;
}
2019-04-05 23:59:31 +08:00
try {
JSONObject siteJson = new JSONObject ( ) ;
siteJson . put ( " chapterUrlPattern " , mSiteRule . getChapterUrlPattern ( ) ) ;
2019-04-20 00:26:49 +08:00
/ * if ( mSiteRule . getDomain ( ) . equals ( " qu.la " ) ) {
siteJson . put ( " chapterUrlRegexOnMulu " , " <dd> <a[^>]*href= \" (/book/[ \\ d]+/[ \\ d]+ \\ .html) \" >([^<]+)</a></dd> " ) ;
} else {
siteJson . put ( " chapterUrlRegexOnMulu " , mSiteRule . getChapterUrlRegexOnMulu ( ) ) ;
} * /
2019-04-28 22:56:27 +08:00
siteJson . put ( " chapterUrlRegexOnMulu " , " " ) ;
2019-04-20 00:26:49 +08:00
//
2019-04-05 23:59:31 +08:00
mChapters = NovelParseUtil . getChapters ( mSite . getDomain ( ) , url , content , siteJson ) ;
Log . d ( TAG , String . format ( " mulu on Site %s download status %s " , mSite . getDomain ( ) , mMuluStatus ) ) ;
2019-04-28 00:18:56 +08:00
if ( mChapters . size ( ) > mNovel . getChaptCnt ( ) ) {
mNovel . setChaptCnt ( mChapters . size ( ) ) ;
mNovel . update ( mNovel . getId ( ) ) ;
}
2019-04-05 23:59:31 +08:00
} catch ( JSONException e ) {
// } catch (JSONException | IOException e) {
2019-04-28 22:56:27 +08:00
Log . e ( TAG , String . format ( " prepare book, mulu on Site %s download status %s " , mSite . getDomain ( ) , mMuluStatus ) , e ) ;
2019-04-05 23:59:31 +08:00
e . printStackTrace ( ) ;
} finally {
// result.close();
// if (result2 != null) result2.close();
}
2019-04-02 17:41:53 +08:00
}
2019-04-05 23:59:31 +08:00
2019-04-02 17:41:53 +08:00
private void cleanCacheFile ( ) {
File file = new File ( cachedPath ) ;
if ( ! file . exists ( ) ) {
file . mkdir ( ) ;
} else {
File [ ] files = file . listFiles ( ) ;
for ( int i = 0 ; i < files . length ; i + + ) {
files [ i ] . delete ( ) ;
}
}
file = new File ( getChapterPath ( ) ) ;
if ( ! file . exists ( ) ) {
file . mkdir ( ) ;
} else {
File [ ] files = file . listFiles ( ) ;
for ( int i = 0 ; i < files . length ; i + + ) {
files [ i ] . delete ( ) ;
}
}
}
public int next ( boolean back ) {
position + = 1 ;
2019-04-26 23:33:17 +08:00
if ( position > tmpChaptLen ) {
position = tmpChaptLen ;
2019-04-02 17:41:53 +08:00
return - 1 ;
}
char result = chaptCurrent ( ) ; //current();
if ( back ) {
position - = 1 ;
}
return result ;
}
public char [ ] nextLine ( ) {
2019-04-26 23:33:17 +08:00
if ( position > = tmpChaptLen ) {
2019-04-02 17:41:53 +08:00
return null ;
}
String line = " " ;
2019-04-26 23:33:17 +08:00
while ( position < tmpChaptLen ) {
2019-04-02 17:41:53 +08:00
int word = next ( false ) ;
if ( word = = - 1 ) {
break ;
}
char wordChar = ( char ) word ;
if ( ( wordChar + " " ) . equals ( " \ n " ) ) { // if ((wordChar + "").equals("\r") && (((char)next(true)) + "").equals("\n")){
// next(false);
break ;
}
line + = wordChar ;
}
return line . toCharArray ( ) ;
}
public char [ ] preLine ( ) {
if ( position < = 0 ) {
return null ;
}
String line = " " ;
while ( position > = 0 ) {
int word = pre ( false ) ;
if ( word = = - 1 ) {
break ;
}
char wordChar = ( char ) word ;
if ( ( wordChar + " " ) . equals ( " \ n " ) ) { // if ((wordChar + "").equals("\n") && (((char)pre(true)) + "").equals("\r")){
// pre(false); // /r/n ->/n 不需要再往前读一个字符了
// line = "\r\n" + line;
break ;
}
line = wordChar + line ;
}
return line . toCharArray ( ) ;
}
public char chaptCurrent ( ) {
2019-04-25 02:01:18 +08:00
// chapterNo = mChapters.size() < chapterNo ? 1 : chapterNo;
// Log.d(TAG, String.format(" prepare book chaptCurrent() ,chapterNo %s, getChapters().size() %s " ,chapterNo , mChapters.size()) );
2019-04-02 17:41:53 +08:00
char [ ] charArray = chaptChars ( chapterNo ) ;
2019-04-07 23:49:08 +08:00
2019-04-15 23:26:24 +08:00
int i = ( int ) position - 1 ;
2019-04-20 00:26:49 +08:00
i = i < charArray . length ? i : charArray . length - 1 ;
2019-04-15 23:26:24 +08:00
return charArray [ i ] ;
2019-04-02 17:41:53 +08:00
}
public char current ( ) {
// int pos = (int) (position % cachedSize);
// int cachePos = (int) (position / cachedSize);
int cachePos = 0 ;
int pos = 0 ;
int len = 0 ;
for ( int i = 0 ; i < myArray . size ( ) ; i + + ) {
long size = myArray . get ( i ) . getSize ( ) ;
if ( size + len - 1 > = position ) {
cachePos = i ;
pos = ( int ) ( position - len ) ;
break ;
}
len + = size ;
}
char [ ] charArray = block ( cachePos ) ;
return charArray [ pos ] ;
}
public int pre ( boolean back ) {
position - = 1 ;
if ( position < 0 ) {
position = 0 ;
return - 1 ;
}
char result = current ( ) ;
if ( back ) {
position + = 1 ;
}
return result ;
}
public long getPosition ( ) {
return position ;
}
public void setPostition ( long position ) {
this . position = position ;
}
//缓存书本
private void cacheBook ( ) throws IOException {
2019-04-03 18:09:00 +08:00
if ( TextUtils . isEmpty ( mNovel . getCharset ( ) ) ) {
2019-04-02 17:41:53 +08:00
m_strCharsetName = FileUtils . getCharset ( bookPath ) ;
if ( m_strCharsetName = = null ) {
m_strCharsetName = " utf-8 " ;
}
ContentValues values = new ContentValues ( ) ;
values . put ( " charset " , m_strCharsetName ) ;
2019-04-03 18:09:00 +08:00
LitePal . update ( Novel . class , values , mNovel . getId ( ) ) ;
2019-04-02 17:41:53 +08:00
} else {
2019-04-03 18:09:00 +08:00
m_strCharsetName = mNovel . getCharset ( ) ;
2019-04-02 17:41:53 +08:00
}
File file = new File ( bookPath ) ;
InputStreamReader reader = new InputStreamReader ( new FileInputStream ( file ) , m_strCharsetName ) ;
int index = 0 ;
bookLen = 0 ;
2019-04-03 18:09:00 +08:00
mChapters . clear ( ) ;
2019-04-02 17:41:53 +08:00
myArray . clear ( ) ;
while ( true ) {
char [ ] buf = new char [ cachedSize ] ;
int result = reader . read ( buf ) ;
if ( result = = - 1 ) {
reader . close ( ) ;
break ;
}
String bufStr = new String ( buf ) ;
// Log.e(TAG,String.format("缓存的内容是\n %s",bufStr));
bufStr = bufStr . replaceAll ( " \ r \ n " , " \ n " ) ;
// bufStr = bufStr.replaceAll("\u3000\u3000+[ ]*","\u3000\u3000");
bufStr = bufStr . replaceAll ( " \ n+ \\ s* " , " \ n \ u3000 \ u3000 " ) ; // bufStr = bufStr.replaceAll("\r\n+\\s*","\r\n\u3000\u3000");
// bufStr = bufStr.replaceAll("\r\n[ {0,}]","\r\n\u3000\u3000");
// bufStr = bufStr.replaceAll(" ","");
bufStr = bufStr . replaceAll ( " \ u0000 " , " " ) ;
buf = bufStr . toCharArray ( ) ;
bookLen + = buf . length ;
// Log.e(TAG,String.format("缓存的内容脱空格处理后\n %s",bufStr));
Cache cache = new Cache ( ) ;
cache . setSize ( buf . length ) ;
cache . setData ( new WeakReference < char [ ] > ( buf ) ) ;
// bookLen += result;
myArray . add ( cache ) ;
// myArray.add(new WeakReference<char[]>(buf));
// myArray.set(index,);
Log . e ( TAG , String . format ( " 缓存的内容写入文件 \ n %s " , fileName ( index ) ) ) ;
Log . e ( TAG , " --------------------------------------------------------------------------------------------------------- " ) ;
try {
File cacheBook = new File ( fileName ( index ) ) ;
if ( ! cacheBook . exists ( ) ) {
cacheBook . createNewFile ( ) ;
}
final OutputStreamWriter writer = new OutputStreamWriter ( new FileOutputStream ( fileName ( index ) ) , " UTF-16LE " ) ; // UTF-16LE 比 utf-8 文件小
writer . write ( buf ) ;
writer . close ( ) ;
} catch ( IOException e ) {
throw new RuntimeException ( " Error during writing " + fileName ( index ) ) ;
}
index + + ;
}
chaptId = 0 ; //初始化导入的chapid
int endchp = myArray . size ( ) > 3 ? 3 : myArray . size ( ) ;
getChapter ( 1 , 3 ) ; //先导入2个部分 立即进行阅读
new Thread ( ) {
@Override
public void run ( ) {
getChapter ( 4 , myArray . size ( ) ) ; //剩余部分后台导入
}
} . start ( ) ;
}
int chaptId = 0 ;
//获取章节
public synchronized void getChapter ( int startblk , int endblk ) {
if ( endblk < startblk ) return ;
try {
long size = 0 ;
String title = " " ;
long start = 0 ;
int chaptFileId = 0 ;
2019-04-03 16:21:00 +08:00
Chapter bookChapter = null ;
2019-04-02 17:41:53 +08:00
OutputStreamWriter writer = null ;
for ( int i = startblk - 1 ; i < endblk ; i + + ) {
char [ ] buf = block ( i ) ;
String bufStr = new String ( buf ) ;
String [ ] paragraphs = bufStr . split ( lineBreakChar ) ; // String[] paragraphs = bufStr.split("\r\n");
for ( String str : paragraphs ) {
// if (str.length() <= 30 && (str.matches(".*第.{1,8}章.*") || str.matches(".*第.{1,8}节.*"))) {
if ( isChapterTitle ( str ) ) {
if ( title . length ( ) = = 0 ) {
title = str ;
start = 0 ;
} else {
start = size ;
title = str ;
}
if ( bookChapter ! = null ) {
bookChapter . setLength ( ( int ) ( size - start ) ) ;
bookChapter . setChapterPath ( fileChapterName ( chaptId ) ) ;
bookChapter . update ( bookChapter . getId ( ) ) ;
2019-04-03 18:09:00 +08:00
mChapters . add ( bookChapter ) ;
2019-04-02 17:41:53 +08:00
}
2019-04-03 16:21:00 +08:00
bookChapter = new Chapter ( ) ;
2019-04-03 18:09:00 +08:00
bookChapter . setNovelId ( mNovel . getId ( ) ) ;
2019-04-03 16:21:00 +08:00
bookChapter . setNovelChapterStartPos ( start ) ;
2019-04-02 17:41:53 +08:00
bookChapter . setChapterName ( str . replaceAll ( " ### " , " " ) ) ;
2019-04-03 16:21:00 +08:00
bookChapter . setNovelPath ( bookPath ) ;
2019-04-02 17:41:53 +08:00
bookChapter . save ( ) ;
int id = bookChapter . getId ( ) ;
Log . d ( TAG , str + " chaptId is " + id ) ;
File chapter = new File ( fileChapterName ( + + chaptId ) ) ;
if ( ! chapter . exists ( ) ) {
chapter . createNewFile ( ) ;
}
if ( writer ! = null ) {
writer . close ( ) ;
}
writer = new OutputStreamWriter ( new FileOutputStream ( fileChapterName ( chaptId ) ) , charachterType ) ;
}
if ( writer = = null ) {
2019-04-03 16:21:00 +08:00
bookChapter = new Chapter ( ) ;
2019-04-03 18:09:00 +08:00
bookChapter . setNovelId ( mNovel . getId ( ) ) ;
2019-04-03 16:21:00 +08:00
bookChapter . setNovelChapterStartPos ( start ) ;
2019-04-02 17:41:53 +08:00
bookChapter . setChapterName ( str . replaceAll ( " ### " , " " ) ) ;
2019-04-03 16:21:00 +08:00
bookChapter . setNovelPath ( bookPath ) ;
2019-04-02 17:41:53 +08:00
bookChapter . save ( ) ;
writer = new OutputStreamWriter ( new FileOutputStream ( fileChapterName ( + + chaptId ) ) , charachterType ) ; //序
}
str + = lineBreakChar ;
writer . write ( str ) ;
// Log.e(TAG,String.format("当前行\n %s",str));
if ( str . contains ( " \ u3000 \ u3000 " ) ) {
size + = str . length ( ) + 2 ;
} else if ( str . contains ( " \ u3000 " ) ) {
size + = str . length ( ) + 1 ;
} else {
size + = str . length ( ) ;
}
/ *
2019-04-03 16:21:00 +08:00
Chapter bookChapter = new Chapter ( ) ;
2019-04-03 18:09:00 +08:00
bookChapter . setBookId ( mNovel . getId ( ) ) ;
2019-04-02 17:41:53 +08:00
bookChapter . setBookChapterStartPos ( start ) ;
bookChapter . setChapterName ( title . replaceAll ( " ### " , " " ) ) ;
bookChapter . setBookpath ( bookPath ) ;
bookChapter . setLength ( ( int ) ( size - start ) ) ;
bookChapter . save ( ) ;
int id = bookChapter . getId ( ) ;
Log . d ( TAG , str + " chaptId is " + id ) ;
2019-04-03 18:09:00 +08:00
mChapters . add ( bookChapter ) ;
2019-04-02 17:41:53 +08:00
* /
}
}
if ( writer ! = null ) {
writer . close ( ) ;
}
if ( bookChapter ! = null ) {
bookChapter . setLength ( ( int ) ( size - start ) ) ;
bookChapter . setChapterPath ( fileChapterName ( chaptId ) ) ;
bookChapter . update ( bookChapter . getId ( ) ) ;
2019-04-03 18:09:00 +08:00
mChapters . add ( bookChapter ) ;
2019-04-02 17:41:53 +08:00
}
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
}
void createChapContent ( ) {
}
2019-04-05 23:59:31 +08:00
public List < Chapter > getmChapters ( ) {
2019-04-03 18:09:00 +08:00
return mChapters ;
2019-04-02 17:41:53 +08:00
}
public long getBookLen ( ) {
return bookLen ;
}
protected String fileName ( int index ) {
2019-04-05 23:59:31 +08:00
return cachedPath + mNovel . getName ( ) + index ;
2019-04-02 17:41:53 +08:00
}
2019-04-18 23:34:19 +08:00
public String fileChapterName ( int chaptId ) {
2019-04-07 23:49:08 +08:00
if ( ! TextUtils . isEmpty ( mNovel . getDomain ( ) ) ) {
2019-04-02 17:41:53 +08:00
2019-04-06 23:04:42 +08:00
return getChapterPath ( ) + mNovel . getDomain ( ) + " / " + chaptId ;
2019-04-05 23:59:31 +08:00
}
2019-04-02 17:41:53 +08:00
return getChapterPath ( ) + chaptId ;
}
String getChapterPath ( ) {
2019-04-05 23:59:31 +08:00
File file = new File ( chapterPath + mNovel . getId ( ) ) ;
if ( ! file . exists ( ) ) {
file . mkdir ( ) ;
}
2019-04-03 18:09:00 +08:00
return chapterPath + mNovel . getId ( ) + " / " ;
2019-04-02 17:41:53 +08:00
}
//获取书本缓存
public char [ ] block ( int index ) {
if ( myArray . size ( ) = = 0 ) {
return new char [ 1 ] ;
}
char [ ] block = myArray . get ( index ) . getData ( ) . get ( ) ;
if ( block = = null ) {
try {
File file = new File ( fileName ( index ) ) ;
int size = ( int ) file . length ( ) ;
if ( size < 0 ) {
throw new RuntimeException ( " Error during reading " + fileName ( index ) ) ;
}
block = new char [ size / 2 ] ;
InputStreamReader reader =
new InputStreamReader (
new FileInputStream ( file ) ,
" UTF-16LE "
) ;
if ( reader . read ( block ) ! = block . length ) {
throw new RuntimeException ( " Error during reading " + fileName ( index ) ) ;
}
reader . close ( ) ;
} catch ( IOException e ) {
throw new RuntimeException ( " Error during reading " + fileName ( index ) ) ;
}
Cache cache = myArray . get ( index ) ;
cache . setData ( new WeakReference < char [ ] > ( block ) ) ;
// myArray.set(index, new WeakReference<char[]>(block));
}
return block ;
}
2019-04-05 23:59:31 +08:00
boolean isDownloadChapt = false ;
2019-04-07 23:49:08 +08:00
synchronized boolean getDownloadStatus ( ) {
return isDownloadChapt ;
}
synchronized void setDownloadFlag ( boolean flag ) {
2019-04-05 23:59:31 +08:00
isDownloadChapt = flag ;
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " set download flat " , isDownloadChapt ) ) ;
2019-04-05 23:59:31 +08:00
}
2019-04-18 17:19:42 +08:00
public ChangeSource pagefactory ;
Handler handler = new Handler ( ) {
2019-04-05 23:59:31 +08:00
@Override
public void handleMessage ( Message msg ) {
int wt = msg . what ;
2019-04-18 17:19:42 +08:00
handlerMsg ( msg ) ;
2019-04-07 23:49:08 +08:00
2019-04-05 23:59:31 +08:00
}
} ;
2019-04-18 17:19:42 +08:00
void handlerMsg ( Message msg ) {
if ( msg . what = = 123 ) {
isDownloadChapt = true ;
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " handler msg, download %s " , isDownloadChapt ) ) ;
2019-04-18 17:19:42 +08:00
} else if ( msg . what = = 1 ) {
isDownloadChapt = true ;
// Toast.makeText(mContext,"网络错误",Toast.LENGTH_LONG).show();
} else if ( msg . what = = 3 ) { //change source
isChangeSource = false ;
Log . d ( TAG , " changing Source:successed get chapters for " + mSite . getDomain ( ) ) ;
/ * if ( isChangeSource ) {
Log . d ( TAG , " changing Source:successed get chapters for " + mSite . getDomain ( ) ) ;
isChangeSource = false ;
int chapId = chapterNo ;
if ( mChapters . size ( ) > = mChangeChapId & & mChapters . get ( mChangeChapId - 1 ) ! = null ) {
String title = mChapters . get ( mChangeChapId - 1 ) . getChapterName ( ) ;
Log . d ( TAG , " changing Source:chapter name in new site " + title ) ;
if ( title . equals ( mChangeTitle ) ) {
Log . d ( TAG , " changing Source:successed find chapter by original chaptId " + mChangeChapId + " : " + mChangeTitle ) ;
chapId = mChangeChapId ;
}
} else {
int i = 1 ;
for ( Chapter chapter : mChapters ) {
if ( chapter . getChapterName ( ) . equals ( mChangeTitle ) ) {
Log . d ( TAG , " changing Source:successed find chapter by original title " + i + " : " + mChangeTitle ) ;
chapId = i ;
break ;
}
i + + ;
}
}
chapId = chapId < = mChapters . size ( ) ? chapId : mChapters . size ( ) ;
Log . d ( TAG , " changing Source: to open chapter with new site source " + chapId + " : " + mChangeTitle ) ;
pagefactory . changeChapter ( chapId ) ;
}
* /
}
}
2019-04-26 23:33:17 +08:00
2019-04-08 23:16:20 +08:00
private enum DownloadStatus {
notStart ,
downloading ,
failure ,
success
}
2019-04-18 17:19:42 +08:00
public boolean isChapterContentExist ( int index ) {
char [ ] block = null ;
if ( chaptCache . containsKey ( Integer . valueOf ( index ) ) ) {
block = chaptCache . get ( index ) . getData ( ) . get ( ) ;
}
if ( block = = null ) {
// cleanCacheFile(); //to remove
File file = new File ( fileChapterName ( index ) ) ;
if ( ! file . exists ( ) ) {
2019-04-21 10:57:20 +08:00
2019-04-18 17:19:42 +08:00
new Thread ( ) {
@Override
public void run ( ) {
try {
loadChaptContent ( index ) ;
} catch ( JSONException e ) {
e . printStackTrace ( ) ;
} catch ( InterruptedException e ) {
e . printStackTrace ( ) ;
}
}
} . start ( ) ;
return false ;
}
}
return true ;
}
2019-04-02 17:41:53 +08:00
//获取chapter 缓存
2019-04-15 23:26:24 +08:00
public char [ ] chaptChars ( final int index ) {
2019-04-26 23:33:17 +08:00
// Log.d(TAG, String.format("prepare book begin to load content for chapter %s ------------------------------------------------------------------------->", index));
2019-04-02 17:41:53 +08:00
char [ ] block = null ;
if ( chaptCache . containsKey ( Integer . valueOf ( index ) ) ) {
block = chaptCache . get ( index ) . getData ( ) . get ( ) ;
}
2019-04-25 02:01:18 +08:00
// Log.d(TAG, String.format("prepare book begin to load content for chapter %s", index));
2019-04-02 17:41:53 +08:00
if ( block = = null ) {
2019-04-05 23:59:31 +08:00
// cleanCacheFile(); //to remove
2019-04-02 17:41:53 +08:00
try {
File file = new File ( fileChapterName ( index ) ) ;
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book begin to load content for chapter %s,file exists?%s " , index , file . exists ( ) ) ) ;
2019-04-23 22:45:08 +08:00
if ( ! file . exists ( ) ) {
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book loadChapts---- %s, 目录数量 %s, MuluStatus %s , mChapters.size() %s, thread %s " , mNovel . getName ( ) , mChapters . size ( ) , mMuluStatus
, mChapters . size ( )
, Thread . currentThread ( ) . getName ( ) ) ) ;
2019-04-03 18:09:00 +08:00
2019-04-23 22:45:08 +08:00
if ( mMuluStatus = = null ) {
Log . d ( TAG , String . format ( " prepare book loadChapts---- 还未有目录信息,出错了 %s 目录, 目录数量 %s, MuluStatus %s ,thread %s " , mNovel . getName ( ) , mChapters . size ( ) , mMuluStatus , Thread . currentThread ( ) . getName ( ) ) ) ;
// getTargetSites();
2019-04-15 23:26:24 +08:00
}
2019-04-10 22:19:06 +08:00
int slept = 0 ;
2019-04-23 22:45:08 +08:00
while ( NetUtil . isNetworkConnected ( ) & & slept < 100 & & mMuluStatus = = MuluStatus . isDownloading ) {
2019-04-10 22:19:06 +08:00
try {
Thread . sleep ( 50 ) ;
slept + + ;
2019-04-23 22:45:08 +08:00
Log . d ( TAG , String . format ( " prepare book loadChapts----等待中 %s 目录, 目录数量 %s, slept %s, MuluStatus %s " , mNovel . getName ( ) , mChapters . size ( ) , slept , mMuluStatus ) ) ;
2019-04-15 23:26:24 +08:00
2019-04-10 22:19:06 +08:00
} catch ( InterruptedException e ) {
e . printStackTrace ( ) ;
}
}
2019-04-25 02:01:18 +08:00
if ( ! NetUtil . isNetworkConnected ( ) | | muluRetryCount > = Constants . retryCnt & & ( mChapters = = null | | mChapters . size ( ) = = 0 ) ) {
Log . d ( TAG , String . format ( " prepare book loadChapts----超时。。。或出错了 %s 目录, 目录数量 %s, slept %s, MuluStatus %s,thread %s " , mNovel . getName ( ) , mChapters . size ( ) , slept , mMuluStatus , Thread . currentThread ( ) . getName ( ) ) ) ;
2019-04-20 00:26:49 +08:00
String error = " 网络不给力 " ;
2019-04-23 22:45:08 +08:00
return error . toCharArray ( ) ;
2019-04-06 23:04:42 +08:00
}
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book loadChaptContent----start %s " , new Date ( ) . toString ( ) ) ) ;
2019-04-18 17:19:42 +08:00
2019-04-03 18:09:00 +08:00
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book isDownloadChapt: %s " , isDownloadChapt ) ) ;
2019-04-06 23:04:42 +08:00
2019-04-23 22:45:08 +08:00
if ( ! chaptDownStatus . containsKey ( Integer . valueOf ( index ) ) ) {
chaptDownStatus . put ( index , DownloadStatus . downloading ) ;
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book put chaptDownStatus index %s,start to load chapcontent " , index ) ) ;
2019-04-07 23:49:08 +08:00
loadChaptContent ( index ) ;
}
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book loadChaptContent %s for downloading,isDownload %s , chaptDownStatus %s, thread %s " ,
index , getDownloadStatus ( ) , chaptDownStatus . get ( Integer . valueOf ( index ) ) , Thread . currentThread ( ) . getName ( ) ) ) ;
2019-04-07 23:49:08 +08:00
2019-04-23 22:45:08 +08:00
int maxSleep = 4500 ;
int slepttime = 0 ;
// while(!file.exists() && !getDownloadStatus()){//&& slepttime <maxSleep){
// while( !getDownloadStatus() && slepttime <maxSleep){
2019-04-25 02:01:18 +08:00
/ * while ( NetUtil . isNetworkConnected ( ) & & ! getDownloadStatus ( ) & & chaptDownStatus . get ( Integer . valueOf ( index ) ) = = DownloadStatus . downloading & & slepttime < maxSleep ) {
2019-04-05 23:59:31 +08:00
Thread . sleep ( 50 ) ;
2019-04-23 22:45:08 +08:00
slepttime + = 50 ;
Log . d ( TAG , String . format ( " prepare book loadChaptContent slept %s for downloading,isDownload %s , thread %s " , slepttime , getDownloadStatus ( ) , Thread . currentThread ( ) . getName ( ) ) ) ;
2019-04-25 02:01:18 +08:00
} * /
while ( ! file . exists ( ) & & NetUtil . isNetworkConnected ( ) & & chaptDownStatus . get ( Integer . valueOf ( index ) ) = = DownloadStatus . downloading & & slepttime < maxSleep ) {
Thread . sleep ( 50 ) ;
slepttime + = 50 ;
Log . d ( TAG , String . format ( " prepare book loadChaptContent %s , slept %s for downloading,isDownload %s , thread %s " , index , slepttime , getDownloadStatus ( ) , Thread . currentThread ( ) . getName ( ) ) ) ;
2019-04-03 18:09:00 +08:00
}
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book loadChaptContent slept %s for downloading " , slepttime ) ) ;
2019-04-23 22:45:08 +08:00
2019-04-25 02:01:18 +08:00
if ( chaptDownStatus . get ( Integer . valueOf ( index ) ) = = DownloadStatus . failure ) {
if ( fileRetryCnt . containsKey ( index ) ) {
fileRetryCnt . put ( index , fileRetryCnt . get ( index ) + 1 ) ;
} else {
fileRetryCnt . put ( index , 1 ) ;
}
Log . d ( TAG , String . format ( " prepare book loadChaptContent %s, rertying count %s " , index , fileRetryCnt . get ( index ) ) ) ;
if ( fileRetryCnt . get ( index ) < Constants . retryCnt ) {
Log . d ( TAG , String . format ( " prepare book loadChaptContent ,rertying to download chapt %s " , index ) ) ;
loadChaptContent ( index ) ;
2019-04-21 10:57:20 +08:00
2019-04-25 02:01:18 +08:00
}
}
2019-04-05 23:59:31 +08:00
}
2019-04-07 23:49:08 +08:00
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book %s, file.exists()? %s " , file . getPath ( ) , file . exists ( ) ) ) ;
if ( ! file . exists ( ) ) {
String error = " 下载内容失败 " ;
if ( ! NetUtil . isNetworkConnected ( ) ) {
error = " 连不上网络 " ;
}
Log . d ( TAG , String . format ( " prepare book loadChaptContent retrying " ) ) ;
// return chaptChars( index);
2019-04-23 22:45:08 +08:00
return error . toCharArray ( ) ;
2019-04-05 23:59:31 +08:00
}
2019-04-23 22:45:08 +08:00
if ( mChapters . size ( ) > index & & NetUtil . isNetworkConnected ( ) ) {
2019-04-05 23:59:31 +08:00
2019-04-23 22:45:08 +08:00
if ( ! chaptDownStatus . containsKey ( index + 1 ) | | chaptDownStatus . get ( index + 1 ) . equals ( DownloadStatus . failure ) ) {
2019-04-05 23:59:31 +08:00
2019-04-03 18:09:00 +08:00
2019-04-23 22:45:08 +08:00
File file2 = new File ( fileChapterName ( index + 1 ) ) ;
if ( ! file2 . exists ( ) ) {
Log . d ( TAG , String . format ( " prepare book to load next chapt %s,down status %s " , index + 1 , chaptDownStatus . get ( index + 1 ) ) ) ;
chaptDownStatus . put ( index + 1 , DownloadStatus . downloading ) ;
loadChaptContent ( index + 1 ) ;
}
}
2019-04-02 17:41:53 +08:00
}
2019-04-23 22:45:08 +08:00
if ( index > 1 & & index - 1 < mChapters . size ( ) & & NetUtil . isNetworkConnected ( ) ) {
2019-04-20 00:26:49 +08:00
2019-04-23 22:45:08 +08:00
if ( ! chaptDownStatus . containsKey ( index - 1 ) | | chaptDownStatus . get ( index - 1 ) . equals ( DownloadStatus . failure ) ) {
File file2 = new File ( fileChapterName ( index - 1 ) ) ;
2019-04-20 00:26:49 +08:00
2019-04-23 22:45:08 +08:00
if ( ! file2 . exists ( ) ) {
Log . d ( TAG , String . format ( " prepare book to load pre chapt %s,down status %s " , index - 1 , chaptDownStatus . get ( index - 1 ) ) ) ;
chaptDownStatus . put ( index - 1 , DownloadStatus . downloading ) ;
loadChaptContent ( index - 1 ) ;
}
2019-04-02 17:41:53 +08:00
2019-04-23 22:45:08 +08:00
}
2019-04-20 00:26:49 +08:00
}
2019-04-02 17:41:53 +08:00
2019-04-23 22:45:08 +08:00
int size = ( int ) file . length ( ) ;
2019-04-02 17:41:53 +08:00
if ( size < 0 ) {
2019-04-23 22:45:08 +08:00
Log . e ( TAG , " prepare book chaptChars: Error during reading " + fileChapterName ( index ) ) ;
// throw new RuntimeException("Error during reading " + fileChapterName(index));
2019-04-02 17:41:53 +08:00
}
block = new char [ size / 2 ] ;
2019-04-23 22:45:08 +08:00
InputStreamReader reader = null ;
try {
reader =
new InputStreamReader (
new FileInputStream ( file ) ,
charachterType
) ;
long l = reader . read ( block ) ;
if ( reader . read ( block ) ! = block . length ) {
// throw new RuntimeException("Error during reading " + fileChapterName(index));
}
} catch ( IOException e ) {
e . printStackTrace ( ) ;
} finally {
if ( reader ! = null ) {
reader . close ( ) ;
}
2019-04-02 17:41:53 +08:00
}
2019-04-23 22:45:08 +08:00
} catch ( JSONException | IOException e ) {
2019-04-03 18:09:00 +08:00
e . printStackTrace ( ) ;
2019-04-05 23:59:31 +08:00
} catch ( InterruptedException e ) {
e . printStackTrace ( ) ;
2019-04-02 17:41:53 +08:00
}
Cache cache = new Cache ( ) ;
cache . setSize ( block . length ) ;
cache . setData ( new WeakReference < char [ ] > ( block ) ) ;
chaptCache . put ( index , cache ) ;
// myArray.set(index, new WeakReference<char[]>(block));
}
return block ;
}
2019-04-05 23:59:31 +08:00
2019-04-25 02:01:18 +08:00
Map < Integer , Integer > fileRetryCnt = new HashMap < Integer , Integer > ( ) ;
2019-04-15 23:26:24 +08:00
private void loadChaptContent ( final int chapterIndex ) throws JSONException , InterruptedException {
2019-04-05 23:59:31 +08:00
/ * 章节内容没有缓存在本地
1 . 根据本地的章节网络地址信息 , 读取章节内容到本地 , 若读取失败则
2 . 查询主服务器 , 若有地址更新则更新本地信息 , 并重复1 , 若没有更新地址 , 则地址无效 , 返回章节内容正待手打
* /
//
2019-04-20 00:26:49 +08:00
if ( ! NetUtil . isNetworkConnected ( ) | | mChapters . size ( ) = = 0 ) {
handler . sendEmptyMessage ( 1 ) ;
return ;
}
2019-04-16 23:11:00 +08:00
final int index = mChapters . size ( ) < chapterIndex ? 1 : chapterIndex ;
2019-04-15 23:26:24 +08:00
if ( mChapters . size ( ) < chapterIndex ) {
Log . d ( TAG , String . format ( " loadChaptContent----wrong index, chapter size %s,load index %s,bookname %s " , mChapters . size ( ) , index , mNovel . getName ( ) ) ) ;
2019-04-06 23:04:42 +08:00
2019-04-15 23:26:24 +08:00
}
2019-04-05 23:59:31 +08:00
Chapter chapter = mChapters . get ( index - 1 ) ;
String url = chapter . getChapterUrl ( ) ;
if ( TextUtils . isEmpty ( url ) ) {
2019-04-18 17:19:42 +08:00
handler . sendEmptyMessage ( 1 ) ;
2019-04-05 23:59:31 +08:00
return ;
}
long startTime = new Date ( ) . getTime ( ) ;
Log . d ( TAG , String . format ( " loadChaptContent----start download %s from %s " , chapter . getChapterName ( ) , url ) ) ;
setDownloadFlag ( false ) ;
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " loadChaptContent isDownloadChapt: %s " , isDownloadChapt ) ) ;
2019-04-05 23:59:31 +08:00
JSONObject siteJson = new JSONObject ( ) ;
siteJson . put ( " chapterContentRegex " , mSiteRule . getChapterContentRegex ( ) ) ;
siteJson . put ( " chapterContentDumpRegex " , mSiteRule . getChapterContentDumpRegex ( ) ) ;
2019-04-28 22:56:27 +08:00
Request request = getTagRequest ( url , 0 ) ;
2019-04-05 23:59:31 +08:00
HttpMethods . getOkClient ( ) . newCall ( request ) . enqueue ( new Callback ( ) {
@Override
public void onFailure ( Call call , IOException e ) {
2019-04-20 00:26:49 +08:00
if ( e . toString ( ) . contains ( " closed " ) | | e . getMessage ( ) . contains ( " Canceled " ) )
{
// return;
}
2019-04-25 02:01:18 +08:00
// handler.sendEmptyMessage(123);
// handler.sendEmptyMessage(1);
2019-04-08 23:16:20 +08:00
chaptDownStatus . put ( index , DownloadStatus . failure ) ;
2019-04-05 23:59:31 +08:00
setDownloadFlag ( true ) ;
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book loadChaptContent fail, isDownloadChapt: %s " , isDownloadChapt ) ) ;
2019-04-07 23:49:08 +08:00
e . printStackTrace ( ) ;
// throw new RuntimeException("Error during writing " + fileChapterName( index));
2019-04-05 23:59:31 +08:00
}
@Override
public void onResponse ( Call call , Response response ) {
ResponseBody body = response . body ( ) ;
if ( body ! = null ) {
if ( response . code ( ) ! = 200 ) {
2019-04-25 02:01:18 +08:00
Log . d ( TAG , " prepare book loadChaptContent----network failure returnCode " + response . code ( ) ) ;
2019-04-05 23:59:31 +08:00
setDownloadFlag ( true ) ;
2019-04-08 23:16:20 +08:00
chaptDownStatus . put ( index , DownloadStatus . failure ) ;
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book loadChaptContent error %s ,isDownloadChapt: %s " , response . code ( ) , isDownloadChapt ) ) ;
2019-04-05 23:59:31 +08:00
handler . sendEmptyMessage ( 1 ) ;
return ;
}
try {
2019-04-16 23:11:00 +08:00
2019-04-05 23:59:31 +08:00
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 ( index ) ) ;
file . createNewFile ( ) ;
final OutputStreamWriter writer = new OutputStreamWriter ( new FileOutputStream ( fileChapterName ( index ) ) , charachterType ) ; //"UTF-16LE"); // UTF-16LE 比 utf-8 文件小
writer . write ( buf ) ;
writer . close ( ) ;
2019-04-25 02:01:18 +08:00
Log . d ( TAG , String . format ( " prepare book loadChaptContent file created: %s, thread %s " , file . getPath ( ) , Thread . currentThread ( ) . getName ( ) ) ) ;
2019-04-07 23:49:08 +08:00
handler . sendEmptyMessage ( 123 ) ;
setDownloadFlag ( true ) ;
2019-04-05 23:59:31 +08:00
} catch ( IOException | JSONException e ) {
e . printStackTrace ( ) ;
2019-04-28 00:18:56 +08:00
Log . e ( TAG , " onResponse: prepare book error " , e ) ;
chaptDownStatus . put ( index , DownloadStatus . failure ) ;
return ;
// throw new RuntimeException("Error during writing " + fileChapterName( index));
2019-04-05 23:59:31 +08:00
}
finally {
body . close ( ) ;
handler . sendEmptyMessage ( 123 ) ;
2019-04-07 23:49:08 +08:00
setDownloadFlag ( true ) ;
2019-04-05 23:59:31 +08:00
}
chapter . setNovelId ( mNovel . getId ( ) ) ;
chapter . setChapterPath ( fileChapterName ( index ) ) ;
2019-04-28 00:18:56 +08:00
if ( chapter . getId ( ) > 0 ) {
chapter . update ( chapter . getId ( ) ) ;
} else {
chapter . save ( ) ;
}
2019-04-07 23:49:08 +08:00
setDownloadFlag ( true ) ;
2019-04-08 23:16:20 +08:00
chaptDownStatus . put ( index , DownloadStatus . success ) ;
2019-04-16 23:11:00 +08:00
Log . d ( TAG , String . format ( " prepare book loadChaptContent---- finished download %s, cost time %s ,content path %s ,thread %s " , chapter . getChapterName ( ) , new Date ( ) . getTime ( ) - startTime , chapter . getChapterPath ( ) , Thread . currentThread ( ) . getName ( ) ) ) ;
2019-04-05 23:59:31 +08:00
}
}
} ) ;
}
2019-04-28 22:56:27 +08:00
/ * * *
*
* @param url
* @param maxAge
* @return
* /
private Request getTagRequest ( String url , int maxAge ) {
Request . Builder builder = new Request . Builder ( )
2019-04-05 23:59:31 +08:00
. tag ( mNovel . getNovelId ( ) ) //标记 请求的tag,切换小说或离开小说界面(BookActivity) 时 取消未执行完毕的 此tag的所有请求
. url ( url )
2019-04-28 22:56:27 +08:00
. removeHeader ( " Pragma " )
. header ( " Cache-Control " , " public, max-age= " + 0 )
// .header("Accept-Encoding","gzip, deflate, sdch")
. header ( " Accept-Language " , " zh-CN,zh;q=0.9 " )
. header ( " Accept " , " text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 " )
. header ( " Upgrade-Insecure-Requests " , " 1 " )
;
return builder . build ( ) ;
2019-04-05 23:59:31 +08:00
}
2019-04-02 17:41:53 +08:00
public boolean isChapterTitle ( String line ) {
return ( line . length ( ) < = 30 & & ( line . matches ( " .*第.{1,8}章.* " ) | | line . matches ( " .*第.{1,8}节.* " ) ) ) ;
}
2019-04-05 23:59:31 +08:00
2019-04-02 17:41:53 +08:00
}