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-05 23:59:31 +08:00
import android.os.Handler ;
import android.os.Looper ;
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 ;
2019-04-06 23:04:42 +08:00
import com.novelbook.android.BookActivity ;
2019-04-05 23:59:31 +08:00
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-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 ;
2019-04-05 23:59:31 +08:00
import java.io.Console ;
2019-04-02 17:41:53 +08:00
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 ;
public void setNovelSites ( NovelSites nvs ) {
this . mNovelSites = nvs ;
2019-04-15 23:26:24 +08:00
Log . d ( TAG , String . format ( " prepare book %s get novel sites count . " , 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 ( ) {
BookSubscribe . getNovelSites ( mNovel . getNovelId ( ) , new OnSuccessAndFaultSub ( new OnSuccessAndFaultListener ( ) {
@Override
public void onSuccess ( String result ) {
//成功
try {
2019-04-15 23:26:24 +08:00
Log . d ( TAG , String . format ( " prepare book %s get target sites done. " , mNovel . 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 ) {
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-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 ) {
//成功
SiteRule sr = ( SiteRule ) gson . fromJson ( result , SiteRule . class ) ;
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-15 23:26:24 +08:00
Log . d ( TAG , String . format ( " prepare book %s 目录正则表达式下载完成,开始读章节信息. " , mNovel . getName ( ) ) ) ;
2019-04-10 22:19:06 +08:00
Log . d ( TAG , String . format ( " 目录正则表达式下载完成,开始读取章节信息 " ) ) ;
2019-04-05 23:59:31 +08:00
readChaptersAsync ( ) ;
}
@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 ( ) ) {
chapterNo = 1 ;
}
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-05 23:59:31 +08:00
enum MuluStatus {
isDownloading ,
isDone ,
failed
}
private void showProgressDialog ( ) {
if ( null = = progressDialog ) {
progressDialog = new ProgressDialog ( mContext ) ;
}
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
}
private void checkAndCreateDir ( String path ) {
File file = new File ( path ) ;
if ( ! file . exists ( ) ) {
file . mkdir ( ) ;
}
}
2019-04-05 23:59:31 +08:00
public synchronized void openBook ( Novel novel ) throws IOException , InterruptedException {
2019-04-03 18:09:00 +08:00
this . mNovel = novel ;
2019-04-02 17:41:53 +08:00
//如果当前缓存不是要打开的书本就缓存书本同时删除缓存
//TODO 构建新的缓存策略, 几个选项, 1: 每本书一个缓存 2: 控制缓存总大小, 超过限制删除旧缓存 3: 网络小说的缓存
2019-04-09 22:32:02 +08:00
boolean isLocalImport = novel . isLocalBook ( ) ;
2019-04-03 18:09:00 +08:00
boolean isOnShelf = isLocalImport | | novel . isOnShelf ( ) ;
boolean isLoadChaptsFromRemote = ! isLocalImport ; // && !novel.isFinished() ; //是否从目标网站下载目录
2019-04-07 23:49:08 +08:00
// showProgressDialog();
2019-04-03 18:09:00 +08:00
if ( isLocalImport ) {
2019-04-02 17:41:53 +08:00
2019-04-03 18:09:00 +08:00
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 > ( ) ;
2019-04-05 23:59:31 +08:00
if ( mChapters . isEmpty ( ) ) { //1. 首次打开 本地导入的书
2019-04-03 18:09:00 +08:00
if ( bookPath = = null | | ! bookPath . equals ( mNovel . getNovelPath ( ) ) ) {
cleanCacheFile ( ) ;
this . bookPath = mNovel . getNovelPath ( ) ;
bookName = FileUtils . getFileName ( bookPath ) ;
cacheBook ( ) ;
}
2019-04-02 17:41:53 +08:00
}
2019-04-05 23:59:31 +08:00
} else { //读取目录列表
MuluStatus m = mMuluStatus ;
2019-04-06 23:04:42 +08:00
// Log.d(TAG,String.format("mulu on Site %s download status %s",mSite.getDomain(),mMuluStatus));
2019-04-15 23:26:24 +08:00
Log . d ( TAG , String . format ( " prepare book %s open book in background.... mMuluStatus %s, mSiteRule %s " , mNovel . getName ( ) , mMuluStatus , mSiteRule ) ) ;
while ( mSiteRule = = null | | mMuluStatus = = MuluStatus . isDownloading ) {
2019-04-05 23:59:31 +08:00
Thread . sleep ( 50 ) ;
2019-04-15 23:26:24 +08:00
Log . d ( TAG , String . format ( " prepare book waiting for mulu downloading ,mMuluStatus %s,msiteRule %s " , mMuluStatus , mSiteRule ) ) ;
2019-04-06 23:04:42 +08:00
if ( mMuluStatus = = MuluStatus . failed ) {
2019-04-07 23:49:08 +08:00
dismissProgressDialog ( ) ;
2019-04-06 23:04:42 +08:00
throw new RuntimeException ( " 读取资源失败,请检查网络 " ) ;
}
2019-04-05 23:59:31 +08:00
}
}
2019-04-07 23:49:08 +08:00
// dismissProgressDialog();
2019-04-05 23:59:31 +08:00
}
// String getMuluUrl() {
// return "https://www.qu.la/book/390/";
// }
/ * void readChapters ( String url ) {
Request request = getTagRequest ( url ) ;
ResponseBody body = null ;
try {
long startTime = new Date ( ) . getTime ( ) ;
Log . d ( TAG , String . format ( " loadChaptContent----start download %s 目录 from %s " , mNovel . getName ( ) , url ) ) ;
Response response = HttpMethods . getOkClient ( ) . newCall ( request ) . execute ( ) ;
Log . d ( TAG , String . format ( " loadChaptContent----end download %s 目录, 目录数量 %s, cost %s " , mNovel . getName ( ) , mChapters . size ( ) , new Date ( ) . getTime ( ) - startTime ) ) ;
startTime = new Date ( ) . getTime ( ) ;
body = response . body ( ) ;
String bodyStr = body . string ( ) ;
Log . d ( TAG , " onResponse: " + bodyStr ) ;
buildCharacters ( bodyStr , url ) ;
Log . d ( TAG , String . format ( " loadChaptContent----end build %s 目录, 目录数量 %s, cost %s " , mNovel . getName ( ) , mChapters . size ( ) , new Date ( ) . getTime ( ) - startTime ) ) ;
} catch ( IOException e ) {
e . printStackTrace ( ) ;
} finally {
if ( body ! = null ) {
body . close ( ) ; ;
}
2019-04-02 17:41:53 +08:00
}
2019-04-03 18:09:00 +08:00
2019-04-05 23:59:31 +08:00
} * /
void readChaptersAsync ( ) {
String url = mSite . getMuluUrl ( ) ;
Request request = getTagRequest ( url ) ;
mMuluStatus = MuluStatus . isDownloading ;
long startTime = new Date ( ) . getTime ( ) ;
2019-04-10 22:19:06 +08:00
Log . d ( TAG , String . format ( " loadChapts----start download %s 目录 from %s " , mNovel . getName ( ) , url ) ) ;
2019-04-05 23:59:31 +08:00
HttpMethods . getOkClient ( ) . newCall ( request ) . enqueue ( new Callback ( ) {
@Override
public void onFailure ( Call call , IOException e ) {
Log . d ( TAG , " onFailure: " + e . getMessage ( ) ) ;
2019-04-10 22:19:06 +08:00
Log . d ( TAG , String . format ( " loadChapts---- failed %s 目录 from %s " , mNovel . getName ( ) , url ) ) ;
2019-04-06 23:04:42 +08:00
if ( mNovelSites . getSites ( ) . length = = 1 ) { //仅有一个rule,且失败了
2019-04-05 23:59:31 +08:00
mMuluStatus = MuluStatus . failed ;
return ;
}
//try next site
for ( Site st : mNovelSites . getSites ( ) ) {
if ( ! st . getDomain ( ) . equals ( mSite . getDomain ( ) ) ) {
mSite = st ;
break ;
}
}
// readChaptersAsync();
getSiteRule ( ) ;
}
@Override
public void onResponse ( Call call , Response response ) {
ResponseBody body = response . body ( ) ;
2019-04-06 23:04:42 +08:00
if ( response . code ( ) ! = 200 ) {
2019-04-10 22:19:06 +08:00
Log . d ( TAG , String . format ( " loadChapts----failed, %s 目录 from %s,return code %s " , mNovel . getName ( ) , url , response . code ( ) ) ) ;
2019-04-06 23:04:42 +08:00
mMuluStatus = MuluStatus . failed ;
return ;
}
2019-04-05 23:59:31 +08:00
if ( body ! = null ) {
2019-04-15 23:26:24 +08:00
Log . d ( TAG , String . format ( " prepare book %s 章节信息读取成功. " , mNovel . 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 ) ;
Log . d ( TAG , String . format ( " 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-15 23:26:24 +08:00
void buildChapters ( String content , String url ) {
2019-04-05 23:59:31 +08:00
try {
JSONObject siteJson = new JSONObject ( ) ;
siteJson . put ( " chapterUrlPattern " , mSiteRule . getChapterUrlPattern ( ) ) ;
siteJson . put ( " chapterUrlRegexOnMulu " , mSiteRule . getChapterUrlRegexOnMulu ( ) ) ; //示例接口表达式有问题
2019-04-10 22:19:06 +08:00
// siteJson.put("chapterUrlRegexOnMulu", "<dd> <a[^>]*href=\"(/book/[\\d]+/[\\d]+\\.html)\">([^<]+)</a></dd>");
siteJson . put ( " chapterUrlRegexOnMulu " , mSiteRule . getChapterUrlRegexOnMulu ( ) ) ;
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 ) ) ;
/ * if ( mChapters ! = null ) {
int lastReadChapt = mNovel . getLastReadChapt ( ) ;
// int index =lastReadChapt*2-2;
lastReadChapt = lastReadChapt > = mChapters . size ( ) ? mChapters . size ( ) - 1 : lastReadChapt ;
lastReadChapt = lastReadChapt < = 0 ? 1 : lastReadChapt ;
mCurrentChapter = mChapters . get ( lastReadChapt - 1 ) ;
} * /
} catch ( JSONException e ) {
// } catch (JSONException | IOException e) {
Log . d ( TAG , String . format ( " mulu on Site %s download status %s " , mSite . getDomain ( ) , mMuluStatus ) ) ;
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 ;
if ( position > bookLen ) {
position = bookLen ;
return - 1 ;
}
char result = chaptCurrent ( ) ; //current();
if ( back ) {
position - = 1 ;
}
return result ;
}
public char [ ] nextLine ( ) {
if ( position > = bookLen ) {
return null ;
}
String line = " " ;
while ( position < bookLen ) {
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-15 23:26:24 +08:00
chapterNo = mChapters . size ( ) < = chapterNo ? 1 : chapterNo ;
2019-04-07 23:49:08 +08:00
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 ;
i = i < = charArray . length ? i : charArray . length ;
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
}
protected 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-07 23:49:08 +08:00
Log . d ( " loadChaptContent " , String . format ( " set download flat " , isDownloadChapt ) ) ;
2019-04-05 23:59:31 +08:00
}
2019-04-07 23:49:08 +08:00
final Handler handler = new Handler ( ) {
2019-04-05 23:59:31 +08:00
@Override
public void handleMessage ( Message msg ) {
int wt = msg . what ;
2019-04-07 23:49:08 +08:00
dismissProgressDialog ( ) ;
2019-04-05 23:59:31 +08:00
if ( msg . what = = 123 ) {
isDownloadChapt = true ;
2019-04-07 23:49:08 +08:00
Log . d ( " loadChaptContent " , String . format ( " handler msg, download %s " , isDownloadChapt ) ) ;
2019-04-05 23:59:31 +08:00
} else if ( msg . what = = 1 ) {
2019-04-07 23:49:08 +08:00
isDownloadChapt = true ;
2019-04-10 22:19:06 +08:00
// Toast.makeText(mContext,"网络错误",Toast.LENGTH_LONG).show();
2019-04-05 23:59:31 +08:00
}
}
} ;
2019-04-02 17:41:53 +08:00
private Map < Integer , Cache > chaptCache = new HashMap < Integer , Cache > ( ) ;
2019-04-08 23:16:20 +08:00
private Map < Integer , DownloadStatus > chaptDownStatus = new HashMap < Integer , DownloadStatus > ( ) ;
DownloadStatus downloadStatus = DownloadStatus . notStart ;
private enum DownloadStatus {
notStart ,
downloading ,
failure ,
success
}
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-02 17:41:53 +08:00
char [ ] block = null ;
if ( chaptCache . containsKey ( Integer . valueOf ( index ) ) ) {
block = chaptCache . get ( index ) . getData ( ) . get ( ) ;
}
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-03 18:09:00 +08:00
if ( ! file . exists ( ) ) {
2019-04-15 23:26:24 +08:00
if ( mMuluStatus = = null ) {
Log . d ( TAG , String . format ( " prepare book loadChapts---- 还未有目录信息,出错了 %s 目录, 目录数量 %s, MuluStatus %s " , mNovel . getName ( ) , mChapters . size ( ) , mMuluStatus ) ) ;
getTargetSites ( ) ;
}
2019-04-10 22:19:06 +08:00
int slept = 0 ;
while ( slept < 100 & & mMuluStatus = = MuluStatus . isDownloading ) {
try {
Thread . sleep ( 50 ) ;
slept + + ;
2019-04-15 23:26:24 +08:00
Log . d ( TAG , String . format ( " prepare book loadChapts----等待中 %s 目录, 目录数量 %s, slept %s, MuluStatus %s " , mNovel . getName ( ) , mChapters . size ( ) , slept , mMuluStatus ) ) ;
2019-04-10 22:19:06 +08:00
} catch ( InterruptedException e ) {
e . printStackTrace ( ) ;
}
}
if ( mChapters = = null | | mChapters . size ( ) = = 0 ) {
2019-04-15 23:26:24 +08:00
Log . d ( TAG , String . format ( " loadChapts----超时。。。或出错了 %s 目录, 目录数量 %s, slept %s, MuluStatus %s " , mNovel . getName ( ) , mChapters . size ( ) , slept , mMuluStatus ) ) ;
String error = " 获取目录失败,网络错误,请重试. " + mMuluStatus ;
2019-04-06 23:04:42 +08:00
return error . toCharArray ( ) ;
}
2019-04-05 23:59:31 +08:00
Log . d ( TAG , String . format ( " loadChaptContent----start %s " , new Date ( ) . toString ( ) ) ) ;
2019-04-03 18:09:00 +08:00
2019-04-07 23:49:08 +08:00
//showProgressDialog();//why not show
2019-04-03 18:09:00 +08:00
2019-04-07 23:49:08 +08:00
Log . d ( " loadChaptContent " , String . format ( " begin to load content for chapter %s " , index ) ) ;
Log . d ( " loadChaptContent " , String . format ( " isDownloadChapt: %s " , isDownloadChapt ) ) ;
2019-04-06 23:04:42 +08:00
2019-04-08 23:16:20 +08:00
if ( ! chaptDownStatus . containsKey ( Integer . valueOf ( index ) ) ) {
chaptDownStatus . put ( index , DownloadStatus . downloading ) ;
2019-04-07 23:49:08 +08:00
loadChaptContent ( index ) ;
}
Log . d ( " loadChaptContent " , String . format ( " showing dialog " ) ) ;
// Log.d(TAG,String.format("showing progress diaglog......"));
int maxSleep = 6000 ;
2019-04-05 23:59:31 +08:00
int slepttime = 0 ;
2019-04-07 23:49:08 +08:00
// while(!file.exists() && !getDownloadStatus()){//&& slepttime <maxSleep){
2019-04-08 23:16:20 +08:00
// while( !getDownloadStatus() && slepttime <maxSleep){
2019-04-15 23:26:24 +08:00
while ( ! getDownloadStatus ( ) & & chaptDownStatus . get ( Integer . valueOf ( index ) ) = = DownloadStatus . downloading & & slepttime < maxSleep ) {
2019-04-05 23:59:31 +08:00
Thread . sleep ( 50 ) ;
slepttime + = 50 ;
2019-04-15 23:26:24 +08:00
Log . d ( TAG , String . format ( " prepare book loadChaptContent slept %s for downloading,isDownload %s " , slepttime , getDownloadStatus ( ) ) ) ;
2019-04-03 18:09:00 +08:00
}
2019-04-07 23:49:08 +08:00
Log . d ( " loadChaptContent " , String . format ( " loadChaptContent slept %s for downloading " , slepttime ) ) ;
Log . d ( " loadChaptContent " , String . format ( " dismissing dialog " ) ) ;
dismissProgressDialog ( ) ;
Log . d ( TAG , String . format ( " loadChaptContent slept %s for downloading chaptercontent " , slepttime ) ) ;
2019-04-05 23:59:31 +08:00
}
2019-04-07 23:49:08 +08:00
Log . d ( " loadChaptContent " , String . format ( " %s, file.exists()? %s " , file . getPath ( ) , file . exists ( ) ) ) ;
2019-04-05 23:59:31 +08:00
if ( ! file . exists ( ) ) {
2019-04-07 23:49:08 +08:00
2019-04-15 23:26:24 +08:00
String error = " 网络不给力 " ;
2019-04-05 23:59:31 +08:00
return error . toCharArray ( ) ;
}
if ( mChapters . size ( ) > index ) {
File file2 = new File ( fileChapterName ( index + 1 ) ) ;
if ( ! file2 . exists ( ) ) {
loadChaptContent ( index + 1 ) ;
}
2019-04-03 18:09:00 +08:00
2019-04-02 17:41:53 +08:00
}
int size = ( int ) file . length ( ) ;
if ( size < 0 ) {
throw new RuntimeException ( " Error during reading " + fileChapterName ( index ) ) ;
}
block = new char [ size / 2 ] ;
InputStreamReader 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));
}
reader . close ( ) ;
} catch ( IOException e ) {
e . printStackTrace ( ) ;
throw new RuntimeException ( " Error during reading " + fileChapterName ( index ) ) ;
2019-04-03 18:09:00 +08:00
} catch ( JSONException e ) {
e . printStackTrace ( ) ;
2019-04-05 23:59:31 +08:00
} catch ( InterruptedException e ) {
e . printStackTrace ( ) ;
2019-04-07 23:49:08 +08:00
} finally {
dismissProgressDialog ( ) ;
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-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-15 23:26:24 +08:00
final int index = mChapters . size ( ) < = chapterIndex ? 1 : chapterIndex ;
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 ) ) {
return ;
}
long startTime = new Date ( ) . getTime ( ) ;
Log . d ( TAG , String . format ( " loadChaptContent----start download %s from %s " , chapter . getChapterName ( ) , url ) ) ;
setDownloadFlag ( false ) ;
2019-04-07 23:49:08 +08:00
Log . d ( " loadChaptContent " , 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 ( ) ) ;
Request request = getTagRequest ( url ) ;
HttpMethods . getOkClient ( ) . newCall ( request ) . enqueue ( new Callback ( ) {
@Override
public void onFailure ( Call call , IOException e ) {
handler . sendEmptyMessage ( 123 ) ;
2019-04-07 23:49:08 +08:00
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-07 23:49:08 +08:00
Log . d ( " loadChaptContent " , String . format ( " loadChaptContent fail, isDownloadChapt: %s " , isDownloadChapt ) ) ;
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-07 23:49:08 +08:00
Log . d ( TAG , " 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-07 23:49:08 +08:00
Log . d ( " loadChaptContent " , String . format ( " loadChaptContent error %s ,isDownloadChapt: %s " , response . code ( ) , isDownloadChapt ) ) ;
2019-04-05 23:59:31 +08:00
handler . sendEmptyMessage ( 1 ) ;
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 ( 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-07 23:49:08 +08:00
Log . d ( " loadChaptContent " , String . format ( " loadChaptContent file created: %s " , file . getPath ( ) ) ) ;
handler . sendEmptyMessage ( 123 ) ;
setDownloadFlag ( true ) ;
2019-04-05 23:59:31 +08:00
} catch ( IOException | JSONException e ) {
e . printStackTrace ( ) ;
throw new RuntimeException ( " Error during writing " + fileChapterName ( index ) ) ;
}
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 ) ) ;
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-05 23:59:31 +08:00
Log . d ( TAG , String . format ( " loadChaptContent---- finished download %s, cost time %s ,content path %s " , chapter . getChapterName ( ) , new Date ( ) . getTime ( ) - startTime , chapter . getChapterPath ( ) ) ) ;
}
}
} ) ;
}
private Request getTagRequest ( String url ) {
return new Request . Builder ( )
. tag ( mNovel . getNovelId ( ) ) //标记 请求的tag,切换小说或离开小说界面(BookActivity) 时 取消未执行完毕的 此tag的所有请求
. url ( url )
// .header("User-Agent", "OkHttp Example")
. build ( ) ;
}
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
}