From dfbd75e6555a1784100ef70ef48d3ab04f82ff9b Mon Sep 17 00:00:00 2001 From: mwang <8205347@qq.com> Date: Tue, 30 Apr 2019 00:35:49 +0800 Subject: [PATCH] fixbug of caching chapt encoding issue --- zhuike/src/main/assets/litepal.xml | 2 +- .../android/Fragments/CatalogFragment.java | 30 +++- .../com/novelbook/android/ReadActivity.java | 6 +- .../android/adapter/CatalogueAdapter.java | 3 + .../com/novelbook/android/db/SiteRule.java | 9 ++ .../android/netutils/EncodingInterceptor.java | 131 ++++++++++++++++++ .../android/netutils/HttpMethods.java | 9 +- .../netutils/OnSuccessAndFaultSub.java | 2 +- .../com/novelbook/android/utils/BookUtil.java | 84 +++++++---- .../android/utils/NovelParseUtil.java | 100 +++++++++++-- .../novelbook/android/utils/PageFactory.java | 17 ++- .../src/main/res/layout/fragment_catalog.xml | 7 +- 12 files changed, 345 insertions(+), 55 deletions(-) create mode 100644 zhuike/src/main/java/com/novelbook/android/netutils/EncodingInterceptor.java diff --git a/zhuike/src/main/assets/litepal.xml b/zhuike/src/main/assets/litepal.xml index 1164b45..ed57089 100644 --- a/zhuike/src/main/assets/litepal.xml +++ b/zhuike/src/main/assets/litepal.xml @@ -2,7 +2,7 @@ - + diff --git a/zhuike/src/main/java/com/novelbook/android/Fragments/CatalogFragment.java b/zhuike/src/main/java/com/novelbook/android/Fragments/CatalogFragment.java index 6ae4f9f..bfb3c17 100644 --- a/zhuike/src/main/java/com/novelbook/android/Fragments/CatalogFragment.java +++ b/zhuike/src/main/java/com/novelbook/android/Fragments/CatalogFragment.java @@ -2,6 +2,7 @@ package com.novelbook.android.Fragments; import android.app.ProgressDialog; import android.os.Bundle; +import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.LinearLayoutManager; import android.text.TextUtils; import android.util.Log; @@ -68,7 +69,7 @@ public class CatalogFragment extends BasicFragment implements MarkActivity.Sortc boolean isFirstLoad = true; @Override protected void fillData() { - catalogueList.clear(); + catalogueList.addAll(pageFactory.getChapters()); // int currentChp =pageFactory.getCurrentChapter()-1; @@ -78,10 +79,8 @@ public class CatalogFragment extends BasicFragment implements MarkActivity.Sortc currentChp = catalogueList.size() -currentChp-1; } - - catalogueAdapter = new CatalogueAdapter(getContext(), catalogueList); + catalogueAdapter.setData(catalogueList); catalogueAdapter.setCharter(currentChp+1); - lv_catalogue.setAdapter(catalogueAdapter); catalogueAdapter.setCahedChapters(catalogCached); catalogueAdapter.notifyDataSetChanged(); @@ -102,8 +101,9 @@ public class CatalogFragment extends BasicFragment implements MarkActivity.Sortc } @OnClick(R.id.btnRefresh) - void refresh(View view){ - loadData() ; + void refresh(View view) { + pageFactory.refreshCate(); + loadData(); } ArrayList revertArray(){ @@ -144,6 +144,10 @@ public class CatalogFragment extends BasicFragment implements MarkActivity.Sortc public void loadData(){ showProgressDialog(false,"请稍等"); + catalogueList.clear(); + catalogueAdapter = new CatalogueAdapter(getContext(), catalogueList); + + lv_catalogue.setAdapter(catalogueAdapter); Log.d(TAG, String .format("prepare book: start to open book cate of %s" , pageFactory.getNovle().getName())); new Thread() { @@ -219,9 +223,23 @@ public class CatalogFragment extends BasicFragment implements MarkActivity.Sortc protected void initViews() { lv_catalogue.setFastScrollEnabled(true); ((MarkActivity) getActivity()).setSortcat(this); + //lv_catalogue.setFastScrollStyle(R.style.FastScrollTheme); //不起作用 } + void initSwipeRefreshLayout(){ + super.initSwipeRefreshLayout(); + mSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + // 开始刷新,设置当前为刷新状态 + //swipeRefreshLayout.setRefreshing(true); + isAsc =true; + refresh(btnRefresh); + + } + }); + } @Override public void setFTag() { diff --git a/zhuike/src/main/java/com/novelbook/android/ReadActivity.java b/zhuike/src/main/java/com/novelbook/android/ReadActivity.java index 74a2307..8738cf8 100644 --- a/zhuike/src/main/java/com/novelbook/android/ReadActivity.java +++ b/zhuike/src/main/java/com/novelbook/android/ReadActivity.java @@ -620,13 +620,15 @@ public class ReadActivity extends Activity_base implements SpeechSynthesizerLis } }*/ else if (id == R.id.action_change_source) { - if( pageFactory.getChapters().size()>0) { + // if( pageFactory.getChapters().size()>0) { Intent intent = new Intent(ReadActivity.this, Activity_ChgSource.class); intent.putExtra(Activity_ChgSource.EXTR_ID, pageFactory.getCurrentChapter()); intent.putExtra(Activity_ChgSource.EXTR_TITLE, pageFactory.getChapterName()); intent.putExtra(Activity_ChgSource.EXTR_SITE, pageFactory.getSite()); startActivity(intent); - } + // }else{ + + // } } return super.onOptionsItemSelected(item); diff --git a/zhuike/src/main/java/com/novelbook/android/adapter/CatalogueAdapter.java b/zhuike/src/main/java/com/novelbook/android/adapter/CatalogueAdapter.java index 61bee2c..9dfcf30 100644 --- a/zhuike/src/main/java/com/novelbook/android/adapter/CatalogueAdapter.java +++ b/zhuike/src/main/java/com/novelbook/android/adapter/CatalogueAdapter.java @@ -50,6 +50,9 @@ public class CatalogueAdapter extends BaseAdapter { public void setCharter(int charter){ currentCharter = charter; } + public void setData(List bookCatalogueList){ + this.bookCatalogueList = bookCatalogueList; + } public void setCahedChapters(List listCached ){ bookCatalogueListCached =listCached; diff --git a/zhuike/src/main/java/com/novelbook/android/db/SiteRule.java b/zhuike/src/main/java/com/novelbook/android/db/SiteRule.java index c0079e2..fc01071 100644 --- a/zhuike/src/main/java/com/novelbook/android/db/SiteRule.java +++ b/zhuike/src/main/java/com/novelbook/android/db/SiteRule.java @@ -13,6 +13,7 @@ public class SiteRule extends LitePalSupport { private String name; @Column(unique = true, nullable = false) private String domain; + private String encoding; // private String chapterUrlRegexOnMulu; private RegexOnMulu[] chapterUrlRegexOnMulu; private String chapterContentDumpRegex; @@ -30,6 +31,14 @@ public class SiteRule extends LitePalSupport { this.id = id; } + public String getEncoding() { + return encoding; + } + + public void setEncoding(String encoding) { + this.encoding = encoding; + } + public String getChapterContentRegex() { return chapterContentRegex; } diff --git a/zhuike/src/main/java/com/novelbook/android/netutils/EncodingInterceptor.java b/zhuike/src/main/java/com/novelbook/android/netutils/EncodingInterceptor.java new file mode 100644 index 0000000..0c40098 --- /dev/null +++ b/zhuike/src/main/java/com/novelbook/android/netutils/EncodingInterceptor.java @@ -0,0 +1,131 @@ +package com.novelbook.android.netutils; + +import android.text.TextUtils; +import android.util.Log; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +import okhttp3.Headers; +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okhttp3.internal.http.RealResponseBody; + +public class EncodingInterceptor implements Interceptor { +private final static String TAG= EncodingInterceptor.class.getSimpleName(); + + /** + * 自定义编码 + */ + private String encoding; + + public EncodingInterceptor(String encoding) { + this.encoding = encoding; + } + + @Override public Response intercept(Interceptor.Chain chain) throws IOException { + Request request = chain.request(); + long start = System.nanoTime(); + Log.d(TAG, String.format("EncodingInterceptor Sending request: %s, headers:%s ", request.url(), request.headers())); + Response response = chain.proceed(request); + long end = System.nanoTime(); + Log.d(TAG,String.format("EncodingInterceptor Received response for %s in %.1fms%n %s", response.request().url(), (end - start) / 1e6d, response.headers()) ); + + + String contentType = response.header("Content-Type"); + if (!TextUtils.isEmpty(contentType) && contentType.contains("charset")) { + return response; + } + + //add header + response.newBuilder() + .removeHeader("Pragma") + .header("Content-Type", (!TextUtils.isEmpty(contentType) ? contentType + "; ":"" ) + "charset=" + encoding) + .build(); + //body charset + /* String contentTypeString = response.body().contentType().charset().name() ; + if (!TextUtils.isEmpty(contentTypeString) && contentTypeString.contains("charset")) { + return response; + } + contentTypeString = (!TextUtils.isEmpty(contentTypeString) ? contentTypeString + "; ":"" ) + "charset=" + encoding; + */ + + + settingClientCustomEncoding(response); + return response; + } + + /** + * setting client custom encoding when server not return encoding + * @param response + * @throws IOException + */ + private void settingClientCustomEncoding(Response response) throws IOException { + // setHeaderContentType(response); + setBodyContentType(response); + } + + /** + * set contentType in headers + * @param response + * @throws IOException + */ + private void setHeaderContentType(Response response) throws IOException { + String contentType = response.header("Content-Type"); + if (!TextUtils.isEmpty(contentType) && contentType.contains("charset")) { + return; + } + + // build new headers + Headers headers = response.headers(); + Headers.Builder builder = headers.newBuilder(); + builder.removeAll("Content-Type"); + builder.add("Content-Type", (!TextUtils.isEmpty(contentType) ? contentType + "; ":"" ) + "charset=" + encoding); + headers = builder.build(); + // setting headers using reflect + Class _response = Response.class; + try { + Field field = _response.getDeclaredField("headers"); + field.setAccessible(true); + field.set(response, headers); + } catch (NoSuchFieldException e) { + throw new IOException("use reflect to setting header occurred an error", e); + } catch (IllegalAccessException e) { + throw new IOException("use reflect to setting header occurred an error", e); + } + } + + /** + * set body contentType + * @param response + * @throws IOException + */ + private void setBodyContentType(Response response) throws IOException { + ResponseBody body = response.body(); + // setting body contentTypeString using reflect + Class tmp = RealResponseBody.class; + if( !(body instanceof RealResponseBody)){ + return; + } + Class aClass = body.getClass(); + try { + Field field = aClass.getDeclaredField("contentTypeString"); + field.setAccessible(true); + /* Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);*/ + String contentTypeString = String.valueOf(field.get(body)); + if (!TextUtils.isEmpty(contentTypeString) && contentTypeString.contains("charset")) { + return; + } + field.set(body, (!TextUtils.isEmpty(contentTypeString) ? contentTypeString + "; ":"" ) + "charset=" + encoding); + } catch (NoSuchFieldException e) { + throw new IOException("use reflect to setting header occurred an error", e); + } catch (IllegalAccessException e) { + throw new IOException("use reflect to setting header occurred an error", e); + } + } +} diff --git a/zhuike/src/main/java/com/novelbook/android/netutils/HttpMethods.java b/zhuike/src/main/java/com/novelbook/android/netutils/HttpMethods.java index 94e2890..33106b4 100644 --- a/zhuike/src/main/java/com/novelbook/android/netutils/HttpMethods.java +++ b/zhuike/src/main/java/com/novelbook/android/netutils/HttpMethods.java @@ -150,9 +150,9 @@ public class HttpMethods { */ Request.Builder requestBuilder = originalRequest.newBuilder() // .addHeader("Accept-Encoding", "gzip") - .addHeader("Accept-Encoding", Locale.getDefault().toString() ) + // .addHeader("Accept-Encoding", Locale.getDefault().toString() ) // .addHeader("Accept", "application/json") - // .addHeader("Content-Type", "application/json; charset=utf-8") + // .addHeader("Content-Type", "application/json; charset=utf-8") // .addHeader("Device", "Android") .removeHeader("User-Agent").addHeader("User-Agent",NetUtil.getUserAgent()) //加 随机agent .tag(NetUtil.currentRequestTag) @@ -178,6 +178,11 @@ public class HttpMethods { loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); //设置 Debug Log 模式 okHttpBuilder.addInterceptor(loggingInterceptor); + + //设置编码 + // EncodingInterceptor encodingInterceptor = new EncodingInterceptor("gbk"); + // okHttpBuilder.addInterceptor(encodingInterceptor); + // } /** diff --git a/zhuike/src/main/java/com/novelbook/android/netutils/OnSuccessAndFaultSub.java b/zhuike/src/main/java/com/novelbook/android/netutils/OnSuccessAndFaultSub.java index 3b84fff..486cda7 100644 --- a/zhuike/src/main/java/com/novelbook/android/netutils/OnSuccessAndFaultSub.java +++ b/zhuike/src/main/java/com/novelbook/android/netutils/OnSuccessAndFaultSub.java @@ -163,7 +163,7 @@ public class OnSuccessAndFaultSub extends DisposableObserver } catch (Exception e2) { Log.e(TAG, "prepare book onError: ",e ); } finally { - Log.e("OnSuccessAndFaultSub", "error:" + e.getMessage()); + Log.e("OnSuccessAndFaultSub", "error:" + e); // mOnSuccessAndFaultListener.onFault("error:" + e.getMessage()); dismissProgressDialog(); progressDialog = null; diff --git a/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java b/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java index bee0fa3..67167b8 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java @@ -30,6 +30,7 @@ import com.novelbook.android.netutils.OnSuccessAndFaultSub; import org.json.JSONException; import org.json.JSONObject; import org.litepal.LitePal; +import org.w3c.dom.Text; import java.io.File; import java.io.FileInputStream; @@ -38,6 +39,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.lang.ref.WeakReference; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -198,15 +200,26 @@ public class BookUtil { throw new RuntimeException("书本错误 code 001"); //无目标网站 // return; } - mSite =nvs.getSites()[0]; - if(nvs.getSites().length > 0) - for (Site site:nvs.getSites() ) { - if(site.getSelectedByDefault()){ - mSite = site; - break; + + if(nvs.getSites().length > 0){ + for (Site site:nvs.getSites() ) { + if(!TextUtils.isEmpty(mNovel.getDomain()) && site.getDomain().equals(mNovel.getDomain())){ + mSite = site; + break; + } } + + if(mSite ==null) + for (Site site:nvs.getSites() ) { + if(site.getSelectedByDefault()){ + mSite = site; + break; + } + } + if(mSite ==null) + mSite =nvs.getSites()[0]; } - getSiteRule(); + getSiteRule(); } private void setSiteInfo() { @@ -252,7 +265,7 @@ public class BookUtil { } },null)); } - private void getSiteRule() { + public void getSiteRule() { mSiteRule = null; BookSubscribe.getSiteRule(mSite.getDomain(),new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() { @Override @@ -296,22 +309,24 @@ public class BookUtil { try { JSONObject siteJson = new JSONObject(result); - chaps = NovelParseUtil.getChapters(mSite.getMuluUrl(), siteJson); + mChapters = NovelParseUtil.getChapters(mSite.getMuluUrl(), siteJson,mSite.getDomain(),mNovel.getMaxAge(),mSiteRule.getEncoding()); - if (chaps != null) - for (String s : chaps) { - Log.d(TAG, "prepare book to get chaps readChaptersAsync: chapt: " + s); + if (mChapters != null){ + for (Chapter chapter:mChapters) { + Log.d(TAG, String.format("prepare book to get chaps readChaptersAsync %s-->%s",chapter.getChapterUrl(), chapter.getChapterName())); } + } + } catch (JSONException e) { Log.e(TAG, "prepare book error on parese :", e); } - if (chaps == null || chaps.length == 0) { + if (mChapters == null ||mChapters.size()== 0) { readChaptersAsync(); }else { - + handler.sendEmptyMessage(3); 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()) ); @@ -700,7 +715,9 @@ int muluRetryCount =0; if (body != null) { Log.d(TAG, String.format("prepare book %s 章节信息读取成功.thread %s",mNovel.getName(),Thread.currentThread().getName()) ); try { - String bodyStr = body.string(); + // String bodyStr = body.string(); + String bodyStr =NovelParseUtil.enconding(body ,mSiteRule.getEncoding()); + // 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(); @@ -785,20 +802,20 @@ int muluRetryCount =0; } - public int next(boolean back){ + public int next(boolean back,int chaptId){ position += 1; if (position > tmpChaptLen){ position = tmpChaptLen; return -1; } - char result = chaptCurrent(); //current(); + char result = chaptCurrent(chaptId); //current(); if (back) { position -= 1; } return result; } - public char[] nextLine(){ + /*public char[] nextLine(){ if (position >= tmpChaptLen){ return null; } @@ -816,7 +833,7 @@ int muluRetryCount =0; line += wordChar; } return line.toCharArray(); - } + }*/ public char[] preLine(){ if (position <= 0){ @@ -839,14 +856,17 @@ int muluRetryCount =0; return line.toCharArray(); } - public char chaptCurrent(){ + + public char chaptCurrent(int chaptId){ // chapterNo = mChapters.size() < chapterNo ? 1 : chapterNo; // Log.d(TAG, String.format(" prepare book chaptCurrent() ,chapterNo %s, getChapters().size() %s " ,chapterNo , mChapters.size()) ); - char[] charArray = chaptChars(chapterNo); + char[] charArray = chaptChars(chaptId); int i = (int)position-1; + i =i>0?i:0; i = i< charArray.length? i:charArray.length-1; + return charArray[i]; } public char current(){ @@ -1258,6 +1278,7 @@ int muluRetryCount =0; char[] block=null; if(chaptCache.containsKey(Integer.valueOf(index))) { block = chaptCache .get(index).getData().get(); + // Log.d(TAG, String.format("prepare book get block in cache, chapter: %s", index)); } // Log.d(TAG, String.format("prepare book begin to load content for chapter %s", index)); if (block == null) { @@ -1389,6 +1410,7 @@ int muluRetryCount =0; new InputStreamReader( new FileInputStream(file), charachterType + // mSiteRule.getEncoding() ); long l = reader.read(block); @@ -1472,6 +1494,7 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte @Override public void onResponse(Call call, Response response){ + ResponseBody body = response.body(); if (body != null ) { if(response.code()!=200){ @@ -1485,7 +1508,13 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte try { - String bodyStr = body.string(); + Charset charset = body.contentType().charset(); + if(charset!=null){ + String name = charset.displayName(); + } + // String bodyStr = body.string(); + // bodyStr =NovelParseUtil.enconding(bodyStr,mSiteRule.getEncoding()); + String bodyStr =NovelParseUtil.enconding(body,mSiteRule.getEncoding()); String title = chapter.getChapterName(); String chapterContent = title+ "\n" + NovelParseUtil.getChapterContent(bodyStr, siteJson); char[] buf = chapterContent.toCharArray(); @@ -1493,6 +1522,7 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte file.createNewFile(); final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(index)), charachterType);//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小 + // final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(index)), mSiteRule.getEncoding() );//charachterType);//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小 writer.write(buf); writer.close(); Log.d( TAG,String.format("prepare book loadChaptContent file created: %s, thread %s", file.getPath(), Thread.currentThread().getName())); @@ -1541,13 +1571,17 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte .tag(mNovel.getNovelId()) //标记 请求的tag,切换小说或离开小说界面(BookActivity) 时 取消未执行完毕的 此tag的所有请求 .url(url) .removeHeader("Pragma") - .header("Cache-Control", "public, max-age=" + 0) - // .header("Accept-Encoding","gzip, deflate, sdch") + .header("Cache-Control", "public, max-age=" + maxAge) + .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") + // .header("content-type", "text/html; charset=utf-8") ; - + /* if(mSiteRule!=null && !TextUtils.isEmpty(mSiteRule.getEncoding()) ){ + builder.header("Accept-Encoding",mSiteRule.getEncoding()); + } +*/ return builder.build(); } diff --git a/zhuike/src/main/java/com/novelbook/android/utils/NovelParseUtil.java b/zhuike/src/main/java/com/novelbook/android/utils/NovelParseUtil.java index ef24829..e9f78a8 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/NovelParseUtil.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/NovelParseUtil.java @@ -1,9 +1,10 @@ package com.novelbook.android.utils; -import android.text.TextUtils; + import android.util.Log; import com.novelbook.android.db.Chapter; +import com.novelbook.android.db.SiteRule; import com.novelbook.android.netutils.HttpMethods; import org.json.JSONArray; @@ -11,8 +12,12 @@ import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -21,6 +26,7 @@ import java.util.Set; import okhttp3.Request; import okhttp3.Response; +import okhttp3.ResponseBody; public class NovelParseUtil { private static final String TAG=NovelParseUtil.class.getSimpleName(); @@ -93,6 +99,9 @@ public class NovelParseUtil { } + + + public static String getChapterContent(String html, JSONObject siteJson) throws JSONException { String chapterContentRegex = siteJson.getString("chapterContentRegex"); String text = REUtil.group(chapterContentRegex, html, 1); @@ -127,7 +136,33 @@ public class NovelParseUtil { - public static String[] getChapters(String url, JSONObject siteJson) throws JSONException { + + + + + public static List getChaptersLst(String[] rows,String domain){ + + ArrayList lst = new ArrayList(); + int j=0; + for (int i=0;i getChapters(String url, JSONObject siteJson,String domain,int maxAage,String encoding) throws JSONException { + return getChaptersLst(getChapters(url,siteJson,maxAage,encoding),domain); + } + + + public static String[] getChapters(String url, JSONObject siteJson, int maxAge,String encoding) throws JSONException { //if (!siteJson.keys().("chapterUrlRegexOnMulu")) return null; String chapterUrlRegexOnMulu = siteJson.getString("chapterUrlRegexOnMulu"); // if(TextUtils.isEmpty(chapterUrlRegexOnMulu)) return null; @@ -152,7 +187,7 @@ public class NovelParseUtil { Log.d(TAG, "to get chaps source:" + source ); if (source.startsWith("html:")) { String _url = source.substring("html:".length()); - source = access(_url); + source = access(_url,maxAge,encoding); Log.d(TAG, "to get chaps source:" + source ); } @@ -241,33 +276,76 @@ public class NovelParseUtil { } - private static String access(String url) { + private static String access(String url,int maxAge,String encoding) { Request.Builder builder = new Request.Builder() // .tag(mNovel.getNovelId()) //标记 请求的tag,切换小说或离开小说界面(BookActivity) 时 取消未执行完毕的 此tag的所有请求 .url(url) .removeHeader("Pragma") - .header("Cache-Control", "public, max-age=" + 0) + .header("Cache-Control", "public, max-age=" + maxAge) // .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") + // .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") + // .header("content-type", "text/html; charset=utf-8") ; Request request =builder.build() ; + Response response = null; try { - Response response = HttpMethods.getOkClient().newCall(request).execute(); - String s =response.body().string(); + response = HttpMethods.getOkClient().newCall(request).execute(); + //String s =response.body().string(); + String s = enconding(response.body(),encoding); //new String(response.body().bytes(), encoding); + // response.body().close(); + long st = new java.util.Date().getTime(); Log.d(TAG, "to get chaps access result:" + s ); - return s; + return s; + // return enconding(s,encoding); + // return info; } catch (IOException e) { e.printStackTrace(); + Log.e(TAG, "access: ", e); + }finally { + if(response!=null) + response.body().close(); } return ""; } +public static String enconding(ResponseBody body, String encode) throws UnsupportedEncodingException { + String s=""; + try{ + Charset charset = body.contentType().charset(); + if(charset!=null){ + s= body.string(); + }else { + s= new String(body.bytes(), encode); + } + }catch (Exception er){ + }finally { + body.close(); + } + return s; + + /* Log.d(TAG, " encoding covert from :" +source ); + long st = new java.util.Date().getTime(); + byte[] b = source.getBytes("utf-8"); + // String info = new String(b, "utf-8"); + String info = new String(b); + Log.d(TAG, " encoding covert to :" +info ); + Log.d(TAG, "encoding covert :" + encode +", cost " +( new Date().getTime() -st)); + return info;*/ + +/* long st = new java.util.Date().getTime(); + byte[] b = source.getBytes(encode); + // String info = new String(b, "utf-8"); + String info = new String(b,"utf-8"); + Log.d(TAG, " encoding covert to :" +info ); + Log.d(TAG, "encoding covert :" + encode +", cost " +( new Date().getTime() -st)); + return info;*/ +} diff --git a/zhuike/src/main/java/com/novelbook/android/utils/PageFactory.java b/zhuike/src/main/java/com/novelbook/android/utils/PageFactory.java index cfee22f..234217b 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/PageFactory.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/PageFactory.java @@ -380,7 +380,7 @@ public class PageFactory implements ChangeSource{ int pageNo =0; while(length getNextLines(){ + public List getNextLines(int chaptId){ List lines = new ArrayList<>(); float width = 0; float height = 0; @@ -1079,8 +1080,8 @@ public static boolean busy(){ lines.add("\n");lines.add("\n"); } calculateLineCount(); - while (mBookUtil.next(true) != -1){ - char word = (char) mBookUtil.next(false); + while (mBookUtil.next(true,chaptId) != -1){ + char word = (char) mBookUtil.next(false,chaptId); //判断是否换行 if ((word + "" ).equals("\n") ){// if ((word + "" ).equals("\r") && (((char) mBookUtil.next(true)) + "").equals("\n")){ // mBookUtil.next(false); @@ -1570,5 +1571,9 @@ public static boolean busy(){ } return new Novel(); } + public void refreshCate(){ + mBookUtil.getChapters().clear(); + mBookUtil.getSiteRule(); + } } diff --git a/zhuike/src/main/res/layout/fragment_catalog.xml b/zhuike/src/main/res/layout/fragment_catalog.xml index fc90f7c..42af75e 100644 --- a/zhuike/src/main/res/layout/fragment_catalog.xml +++ b/zhuike/src/main/res/layout/fragment_catalog.xml @@ -29,6 +29,11 @@ style="@style/TextViewNovelTitle" android:layout_width="match_parent" android:layout_height="wrap_content" /> + - +