diff --git a/zhuike/src/main/assets/litepal.xml b/zhuike/src/main/assets/litepal.xml index ed57089..f9ad3e5 100644 --- a/zhuike/src/main/assets/litepal.xml +++ b/zhuike/src/main/assets/litepal.xml @@ -2,7 +2,7 @@ - + diff --git a/zhuike/src/main/java/com/novelbook/android/Activity_ChgSource.java b/zhuike/src/main/java/com/novelbook/android/Activity_ChgSource.java index bd9f48c..0599ffe 100644 --- a/zhuike/src/main/java/com/novelbook/android/Activity_ChgSource.java +++ b/zhuike/src/main/java/com/novelbook/android/Activity_ChgSource.java @@ -5,6 +5,7 @@ import android.os.Build; import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -26,6 +27,7 @@ import butterknife.ButterKnife; public class Activity_ChgSource extends Activity_base { + private static final String TAG = Activity_ChgSource.class.getSimpleName(); @BindView(R.id.recycleView) @@ -35,10 +37,11 @@ public class Activity_ChgSource extends Activity_base { String chaptTitle; int chaptId; String domain; + // String name; public final static String EXTR_TITLE="title"; public final static String EXTR_ID="id"; public final static String EXTR_SITE="site"; - + //public static final String EXTR_NAME ="" ; PageFactory pageFactory; List mSites; @@ -66,6 +69,7 @@ public class Activity_ChgSource extends Activity_base { chaptId = getIntent().getIntExtra(EXTR_ID,1); domain = getIntent().getStringExtra(EXTR_SITE); + // name = getIntent().getStringExtra(EXTR_NAME); this.setTitle(chaptTitle); } @@ -79,8 +83,8 @@ public class Activity_ChgSource extends Activity_base { public void onItemClick(View view, int position) { Site site = mSites.get(position); - Log.d(TAG, "changing Source: " + site.getDomain()); - pageFactory.changeSource(site.getDomain(),chaptId,chaptTitle); + Log.d(TAG, String.format("changing Source:target site name %s, site domain %s " ,site.getName(), site.getDomain())); + pageFactory.changeSource(site.getName(),site.getDomain(),chaptId,chaptTitle); finish(); } @@ -169,9 +173,13 @@ public class Activity_ChgSource extends Activity_base { @Override public void onBindViewHolder( SiteViewHolder holder, int position) { - String title =mDatas.get(position).getDomain(); + + String title =mDatas.get(position).getName(); + if(TextUtils.isEmpty(title)) { + title = mDatas.get(position).getDomain(); + } Log.d(TAG, String.format("onBindViewHolder: domain is '%s', title is '%s'",domain ,title)); - if(title.equals(domain)){ + if(mDatas.get(position).getDomain().equals(domain)){ title +=" (当前源)"; } diff --git a/zhuike/src/main/java/com/novelbook/android/Fragments/BasicFragment.java b/zhuike/src/main/java/com/novelbook/android/Fragments/BasicFragment.java index 800cc53..e5e250c 100644 --- a/zhuike/src/main/java/com/novelbook/android/Fragments/BasicFragment.java +++ b/zhuike/src/main/java/com/novelbook/android/Fragments/BasicFragment.java @@ -202,7 +202,7 @@ public abstract class BasicFragment extends Fragment { int novelId = novel.getNovelId(); long id = novel.getId(); - + showProgressDialog(false,"正在加载..."); BookSubscribe.getNovel(novel.getNovelId(),new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() { @Override public void onSuccess(String result) { @@ -231,7 +231,7 @@ public abstract class BasicFragment extends Fragment { Log.d(TAG, String.format("prepare book %s 开始open book.",nv.getName()) ); ReadActivity.openBook(nv ,activity); - + handler.sendEmptyMessage(99); } @Override @@ -240,6 +240,7 @@ public abstract class BasicFragment extends Fragment { Toast.makeText(getActivity(),"Novel 请求失败:"+errorMsg,Toast.LENGTH_SHORT).show(); PageFactory.getInstance(activity.getApplicationContext()).prepareBook(novel ); //打开本地小说内容 ReadActivity.openBook(novel ,activity); + handler.sendEmptyMessage(99); } },getActivity())); diff --git a/zhuike/src/main/java/com/novelbook/android/Fragments/BookMarkFragment.java b/zhuike/src/main/java/com/novelbook/android/Fragments/BookMarkFragment.java index 9944353..bd949b6 100644 --- a/zhuike/src/main/java/com/novelbook/android/Fragments/BookMarkFragment.java +++ b/zhuike/src/main/java/com/novelbook/android/Fragments/BookMarkFragment.java @@ -49,7 +49,7 @@ public class BookMarkFragment extends BasicFragment implements MarkActivity.Sor novelId = bundle.getInt(ARGUMENT); } bookMarksList = new ArrayList<>(); - bookMarksList = LitePal.where("novelId = ?", novelId+"").order(String.format("id %s",isAsc ?"asc" :"desc")). find(BookMarks.class); + bookMarksList = LitePal.where("novelId = ? and domain= ?", novelId+"",pageFactory.getSite().getDomain()).order(String.format("id %s",isAsc ?"asc" :"desc")). find(BookMarks.class); Log.d(TAG, "initData: bookmark size " +bookMarksList.size()); markAdapter = new MarkAdapter(getActivity(), bookMarksList); lv_bookmark.setAdapter(markAdapter); @@ -135,4 +135,8 @@ public class BookMarkFragment extends BasicFragment implements MarkActivity.Sor isAsc =!isAsc; initData(); } + @Override + public void refresh() { + + } } 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 bfb3c17..0638488 100644 --- a/zhuike/src/main/java/com/novelbook/android/Fragments/CatalogFragment.java +++ b/zhuike/src/main/java/com/novelbook/android/Fragments/CatalogFragment.java @@ -69,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; @@ -153,7 +153,7 @@ public class CatalogFragment extends BasicFragment implements MarkActivity.Sortc new Thread() { @Override public void run() { - ArrayList list =(ArrayList) LitePal.where("novelId=?" ,pageFactory.getNovle().getId()+"").find(Chapter.class); + ArrayList list =(ArrayList) LitePal.where("novelId=? and domain =? " ,pageFactory.getNovle().getId()+"",pageFactory.getSite().getDomain()).find(Chapter.class); File file; for(Chapter cp : list){ if(!TextUtils.isEmpty(cp.getChapterPath())) { @@ -234,7 +234,7 @@ public class CatalogFragment extends BasicFragment implements MarkActivity.Sortc // 开始刷新,设置当前为刷新状态 //swipeRefreshLayout.setRefreshing(true); - isAsc =true; + // isAsc =true; refresh(btnRefresh); } @@ -268,4 +268,9 @@ public class CatalogFragment extends BasicFragment implements MarkActivity.Sortc } + + @Override + public void refresh() { + refresh(null); + } } diff --git a/zhuike/src/main/java/com/novelbook/android/Fragments/Fragment_Shelf.java b/zhuike/src/main/java/com/novelbook/android/Fragments/Fragment_Shelf.java index 23cf4fe..62e5a0c 100644 --- a/zhuike/src/main/java/com/novelbook/android/Fragments/Fragment_Shelf.java +++ b/zhuike/src/main/java/com/novelbook/android/Fragments/Fragment_Shelf.java @@ -8,6 +8,7 @@ import android.content.Intent; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.BottomSheetDialog; +import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; @@ -34,6 +35,7 @@ import com.novelbook.android.netutils.OnSuccessAndFaultListener; import com.novelbook.android.netutils.OnSuccessAndFaultSub; import com.novelbook.android.utils.Constants; import com.novelbook.android.utils.GsonUtil; +import com.novelbook.android.utils.ImageUtil; import com.novelbook.android.utils.MyImageLoader; import com.novelbook.android.utils.OnItemClickListener; import com.novelbook.android.adapter.BookListAdapter; @@ -92,6 +94,9 @@ public class Fragment_Shelf extends BasicFragment { bookLists = Novel.getNovelsOnShelf(); noveIds=""; for(Novel novel:bookLists){ + if(novel.isFinished()||novel.isLocalBook() ||novel.isUpdated() ){ + continue; + } noveIds+=novel.getNovelId()+","; } } @@ -135,34 +140,7 @@ void test(int maxAge){ * to get updated info from server,TODO: put it in service ,scheduled */ private void getUpdatedData(){ - /* try { - test(3600); - Thread.sleep(1000); - test(3600); - Thread.sleep(1000); - - test(0); - Thread.sleep(1000); - - test(3600); - Thread.sleep(1000); - - test(0); - Thread.sleep(1000); - - test(-1); - Thread.sleep(1000); - - test(3600); - Thread.sleep(1000); - - test(-1); - Thread.sleep(1000); - - } catch (InterruptedException e) { - e.printStackTrace(); - }*/ List novelIds; OnSuccessAndFaultListener successAndFaultListener = new OnSuccessAndFaultListener() { @@ -177,8 +155,13 @@ void test(int maxAge){ for (Novel novel2 : lstUpdate) { novel2.checkAndUpdate(); } - loadNovelsOnShelf(); } + loadNovelsOnShelf(); + + /* for(Novel nove : bookLists){ + + nove.testUpdate(); + }*/ } catch (Exception e) { e.printStackTrace(); @@ -196,8 +179,13 @@ void test(int maxAge){ }; + if(TextUtils.isEmpty(noveIds)){ + loadNovelsOnShelf(); + } if(!TextUtils.isEmpty(noveIds)){ BookSubscribe.getNovelsByIds(noveIds , new OnSuccessAndFaultSub(successAndFaultListener, getActivity())); + }else{ + handler.sendEmptyMessage(1); } } @@ -210,7 +198,7 @@ void test(int maxAge){ // bookLists = LitePal.where("isOnShelf=? or novelId=? ","1","").find(Novel.class); loadNovelsOnShelf(); - getUpdatedData(); + // getUpdatedData(); flag = new boolean[bookLists.size()]; /* if(bookLists.size()>0) { //TODO: to remove @@ -249,6 +237,22 @@ void test(int maxAge){ ((Main2Activity) activity).setShelfFragment(this); } @Override + void initSwipeRefreshLayout(){ + super.initSwipeRefreshLayout(); + mSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + + // 开始刷新,设置当前为刷新状态 + //swipeRefreshLayout.setRefreshing(true); + pageNo=1; + getUpdatedData(); + // TODO 获取数据 + + } + }); + } + @Override public void initViews(){ initReceyleView(); @@ -329,9 +333,14 @@ void test(int maxAge){ bottomSheetDialog.getDelegate().findViewById(android.support.design.R.id.design_bottom_sheet) .setBackgroundColor(getResources().getColor(android.R.color.transparent)); - TextView tv =(TextView) bottomSheetDialog.findViewById(R.id.bdTitle); + TextView tvTitle =(TextView) bottomSheetDialog.findViewById(R.id.bdTitle); - tv.setText(bookLists.get(position).getName()); + tvTitle.setText(bookLists.get(position).getName()); + TextView tvAuthor =(TextView) bottomSheetDialog.findViewById(R.id.tvAuthor); + tvAuthor.setText(bookLists.get(position).getAuthor()); + + ImageView imageView = (ImageView) bottomSheetDialog.findViewById(R.id.imageG1); + ImageUtil.loadImage(activity,bookLists.get(position).getCover(),imageView); LinearLayout lldetail=(LinearLayout) bottomSheetDialog.findViewById(R.id.llBookdetail); lldetail.setOnClickListener(new View.OnClickListener() { @@ -339,6 +348,9 @@ void test(int maxAge){ showBookDetail(bookLists.get(position)); } }); + + + bottomSheetDialog.show(); } @@ -416,6 +428,7 @@ void test(int maxAge){ @Override public void onResume() { super.onResume(); + getUpdatedData(); //TODO: 更新书的状态,是不有更新 } diff --git a/zhuike/src/main/java/com/novelbook/android/MarkActivity.java b/zhuike/src/main/java/com/novelbook/android/MarkActivity.java index 086b184..8c26a58 100644 --- a/zhuike/src/main/java/com/novelbook/android/MarkActivity.java +++ b/zhuike/src/main/java/com/novelbook/android/MarkActivity.java @@ -38,6 +38,9 @@ public class MarkActivity extends Activity_base { // ListView lv_catalogue; @BindView(R.id.btnSort) ImageButton ibSort; + @BindView(R.id.btnRefresh) + ImageButton btnRefresh; + private PageFactory pageFactory; /* private Config config; @@ -97,7 +100,7 @@ public class MarkActivity extends Activity_base { protected void initListener() { } - @OnClick(R.id.btnSort) + @OnClick({R.id.btnSort,R.id.btnRefresh}) void Onclick(View view){ if(view.getId() == R.id.btnSort){ Log.d(TAG, "Onclick: sorted"); @@ -108,6 +111,17 @@ public class MarkActivity extends Activity_base { if(sortmark!=null){ sortmark.sortList(); } + }else{ + if(view.getId() == R.id.btnRefresh){{ + + if(sortcat!=null){ + sortcat.refresh(); + } + if(sortmark!=null){ + sortmark.refresh(); + + } + }} } } @@ -124,8 +138,10 @@ public class MarkActivity extends Activity_base { } public interface Sortmark { public void sortList(); + public void refresh(); } public interface Sortcat { public void sortList(); + public void refresh(); } } diff --git a/zhuike/src/main/java/com/novelbook/android/MyApp.java b/zhuike/src/main/java/com/novelbook/android/MyApp.java index 5f91123..a0bd2a0 100644 --- a/zhuike/src/main/java/com/novelbook/android/MyApp.java +++ b/zhuike/src/main/java/com/novelbook/android/MyApp.java @@ -4,6 +4,7 @@ import android.app.Application; import android.content.Context; import com.novelbook.android.utils.Config; +import com.novelbook.android.utils.LogcatHelper; import com.novelbook.android.utils.PageFactory; import org.litepal.LitePal; @@ -16,7 +17,7 @@ public class MyApp extends Application { applicationContext = getApplicationContext(); Config.createConfig(this); PageFactory.createPageFactory(this); - + LogcatHelper.getInstance(this).start(); // BlurKit.init(this); LitePal.initialize(this); diff --git a/zhuike/src/main/java/com/novelbook/android/ReadActivity.java b/zhuike/src/main/java/com/novelbook/android/ReadActivity.java index 8738cf8..8bca722 100644 --- a/zhuike/src/main/java/com/novelbook/android/ReadActivity.java +++ b/zhuike/src/main/java/com/novelbook/android/ReadActivity.java @@ -587,6 +587,7 @@ public class ReadActivity extends Activity_base implements SpeechSynthesizerLis bookMarks.setNovelId(pageFactory.getNovle().getId()); bookMarks.setChapt(pageFactory.getCurrentChapter()); bookMarks.setChaptName(((pageFactory.getChapters().get(bookMarks.getChapt()-1).getChapterName()))); + bookMarks.setDomain(pageFactory.getSite().getDomain()); bookMarks.save(); Toast.makeText(ReadActivity.this, "书签添加成功", Toast.LENGTH_SHORT).show(); @@ -620,15 +621,17 @@ 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()); + intent.putExtra(Activity_ChgSource.EXTR_ID, pageFactory.getChapter().getIndex()); + intent.putExtra(Activity_ChgSource.EXTR_TITLE, pageFactory.getChapter().getChapterName()); + intent.putExtra(Activity_ChgSource.EXTR_SITE, pageFactory.getChapter().getDomain()); + // intent.putExtra(Activity_ChgSource.EXTR_NAME, pageFactory.getSite().getName()); startActivity(intent); - // }else{ - - // } + hideReadSetting(); + // }else{ + // Toast.makeText(this,"换源不可用,请返回重试...",Toast.LENGTH_SHORT); + // } } return super.onOptionsItemSelected(item); diff --git a/zhuike/src/main/java/com/novelbook/android/adapter/BookListAdapter.java b/zhuike/src/main/java/com/novelbook/android/adapter/BookListAdapter.java index b5c8aeb..2925d4a 100644 --- a/zhuike/src/main/java/com/novelbook/android/adapter/BookListAdapter.java +++ b/zhuike/src/main/java/com/novelbook/android/adapter/BookListAdapter.java @@ -210,7 +210,8 @@ public class BookListAdapter extends RecyclerView.Adapter< RecyclerView.ViewHol if (holder.tvStatus != null) holder.tvStatus.setText(mDatas.get(position).getProgress()); if (holder.imageView != null && !TextUtils.isEmpty(mDatas.get(position).getCover())) { ImageUtil.loadImage(context, mDatas.get(position).getCover(), holder.imageView); - } if (holder.imageUpdate != null) { + } + if (holder.imageUpdate != null) { if( mDatas.get(position).isUpdated()){ holder.imageUpdate.setVisibility(View.VISIBLE); }else{ diff --git a/zhuike/src/main/java/com/novelbook/android/db/BookMarks.java b/zhuike/src/main/java/com/novelbook/android/db/BookMarks.java index 9529ce0..ca85cde 100644 --- a/zhuike/src/main/java/com/novelbook/android/db/BookMarks.java +++ b/zhuike/src/main/java/com/novelbook/android/db/BookMarks.java @@ -14,6 +14,15 @@ public class BookMarks extends LitePalSupport { private String text; private String time; private int novelId; + private String domain; + + public String getDomain() { + return domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } public int getId() { return this.id; diff --git a/zhuike/src/main/java/com/novelbook/android/db/Chapter.java b/zhuike/src/main/java/com/novelbook/android/db/Chapter.java index b1889e9..5b64309 100644 --- a/zhuike/src/main/java/com/novelbook/android/db/Chapter.java +++ b/zhuike/src/main/java/com/novelbook/android/db/Chapter.java @@ -20,6 +20,24 @@ public class Chapter extends LitePalSupport implements Serializable { private String domain; //目标 site private int index;//第几章 + public static Chapter getChapter(int id, String domain, int chapId) { + // Chapter chapter =(Chapter) + + List lst = LitePal.where("novelId=? and domain = ? and index = ?", id + "", domain, chapId + "").limit(1).find(Chapter.class); + if (lst.size() > 0) { + return lst.get(0); + } + + Chapter chapter = new Chapter(); + chapter.setDomain(domain); + chapter.setIndex(chapId); + chapter.setNovelId(id); + chapter.setChapterName(""); + chapter.setChapterUrl(""); + chapter.setChapterPath(""); + return chapter; + } + public int getIndex() { return index; } diff --git a/zhuike/src/main/java/com/novelbook/android/db/Novel.java b/zhuike/src/main/java/com/novelbook/android/db/Novel.java index 9295897..2f16d40 100644 --- a/zhuike/src/main/java/com/novelbook/android/db/Novel.java +++ b/zhuike/src/main/java/com/novelbook/android/db/Novel.java @@ -2,6 +2,7 @@ package com.novelbook.android.db; import android.text.TextUtils; +import android.util.Log; import com.novelbook.android.utils.Constants; @@ -274,7 +275,7 @@ public class Novel extends LitePalSupport implements Serializable{ } public static List getNovelsOnShelf(){ - return LitePal.where("isOnShelf=?","1").find(Novel.class); + return LitePal.where("isOnShelf=?","1").order("isTop desc,isUpdated desc,lastVisit desc" ).find(Novel.class); } public static List getLocalNovels(){ @@ -310,12 +311,24 @@ public class Novel extends LitePalSupport implements Serializable{ setValues(); return super.update(id); } - +public void testUpdate(){ + isUpdated=true; + super.update(id); +} public int checkAndUpdate(){ Novel nv = getNovelBySvrId(novelId); - if(lastUpdateTime > nv.lastVisit || lastUpdateTime > nv.lastUpdateTime){ + /* if(lastUpdateTime > nv.lastVisit && lastUpdateTime > nv.lastUpdateTime){ isUpdated =true; + }*/ + isUpdated =lastUpdateTime > nv.lastVisit && lastUpdateTime > nv.lastUpdateTime; + Log.d("Novel", String.format("book %s server lastUpdateTime %s, local lastupdatetime %s, local lastvist %s" + + "is updated %s,diff1 %s,diff2 %s" + ,name ,lastUpdateTime,nv.lastUpdateTime,nv.lastVisit,isUpdated,lastUpdateTime - nv.lastVisit,lastUpdateTime - nv.lastUpdateTime) ); + + if(!isUpdated){ + setToDefault("isUpdated"); } + return super.update(nv.id); } public int getMaxAge(){ 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 33106b4..b697f02 100644 --- a/zhuike/src/main/java/com/novelbook/android/netutils/HttpMethods.java +++ b/zhuike/src/main/java/com/novelbook/android/netutils/HttpMethods.java @@ -48,7 +48,7 @@ public class HttpMethods { /** * 请求失败重连次数 */ - private int RETRY_COUNT = 3; + private int RETRY_COUNT = 0; private OkHttpClient.Builder okHttpBuilder; private OkHttpClient okHttpClient; //构造方法私有 @@ -56,6 +56,7 @@ public class HttpMethods { okHttpClient = getClient(); + retrofit = new Retrofit.Builder() .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create())//json转换成JavaBean @@ -131,12 +132,15 @@ public class HttpMethods { Cache cache = new Cache(cacheFile, 1024 * 1024 * 50); Log.d(TAG, "getClient: to set cach control"); // okHttpBuilder.cache(cache).addInterceptor(cacheInterceptor); - okHttpBuilder.cache(cache) .addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR) + okHttpBuilder.cache(cache) + //.addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR) .addInterceptor(REWRITE_RESPONSE_INTERCEPTOR_OFFLINE); /** * 设置头信息 */ + + Interceptor headerInterceptor = new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { @@ -154,7 +158,7 @@ public class HttpMethods { // .addHeader("Accept", "application/json") // .addHeader("Content-Type", "application/json; charset=utf-8") // .addHeader("Device", "Android") - .removeHeader("User-Agent").addHeader("User-Agent",NetUtil.getUserAgent()) //加 随机agent + .removeHeader("User-Agent").addHeader("User-Agent",NetUtil.getUserAgent()) //加 随机agent .tag(NetUtil.currentRequestTag) .method(originalRequest.method(), originalRequest.body()); diff --git a/zhuike/src/main/java/com/novelbook/android/netutils/NetUtil.java b/zhuike/src/main/java/com/novelbook/android/netutils/NetUtil.java index 8183d81..c3f0ffb 100644 --- a/zhuike/src/main/java/com/novelbook/android/netutils/NetUtil.java +++ b/zhuike/src/main/java/com/novelbook/android/netutils/NetUtil.java @@ -205,8 +205,8 @@ public class NetUtil { "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24" }; - return uas[new Random().nextInt(uas.length-1)]; - + return uas[new Random().nextInt(uas.length-1)]; + // return "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"; } public static String getCoverUrl(String url){ 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 67167b8..ea0998b 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java @@ -6,6 +6,7 @@ import android.content.Context; import android.os.AsyncTask; +import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.TextUtils; @@ -120,7 +121,13 @@ public class BookUtil { private Map chaptDownStatus = new HashMap(); DownloadStatus downloadStatus = DownloadStatus.notStart; - + public Chapter getChapter(int chapId){ + if(chapId > mChapters.size() || mChapters.size() ==0){ + return Chapter.getChapter(mNovel.getId(), mNovel.getDomain(),chapId); + }else{ + return mChapters.get(chapId-1); + } + } public NovelSites getmNovelSites() { @@ -162,6 +169,8 @@ public class BookUtil { 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; } @@ -265,12 +274,14 @@ public class BookUtil { } },null)); } + + int siteRuleRetryCnt =0; public void getSiteRule() { mSiteRule = null; BookSubscribe.getSiteRule(mSite.getDomain(),new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() { @Override public void onSuccess(String result) { - + siteRuleRetryCnt =0; Log.d(TAG, "prepare book siteRule:" +result); //成功 SiteRule sr= new SiteRule(); @@ -290,6 +301,9 @@ public class BookUtil { sr.save(); } mSiteRule =sr; + if(TextUtils.isEmpty(mSite.getName())){ + mSite.setName(sr.getName()); + }; setSiteInfo(); Log.d(TAG, String.format("prepare book %s 目录正则表达式下载完成,开始读章节信息. muluRegex size %s, thread %s ",mNovel.getName(),mSiteRule.getChapterUrlRegexOnMulu().length, Thread.currentThread().getName()) ); @@ -309,13 +323,13 @@ public class BookUtil { try { JSONObject siteJson = new JSONObject(result); - mChapters = NovelParseUtil.getChapters(mSite.getMuluUrl(), siteJson,mSite.getDomain(),mNovel.getMaxAge(),mSiteRule.getEncoding()); + mChapters = NovelParseUtil.getChapters(mSite.getMuluUrl(), siteJson,mSite.getDomain(),mNovel.getMaxAge(),mSiteRule); - if (mChapters != null){ + /* if (mChapters != null){ for (Chapter chapter:mChapters) { - Log.d(TAG, String.format("prepare book to get chaps readChaptersAsync %s-->%s",chapter.getChapterUrl(), chapter.getChapterName())); + Log.i(TAG, String.format("prepare book to get chaps readChaptersAsync %s-->%s",chapter.getChapterUrl(), chapter.getChapterName())); } - } + }*/ } catch (JSONException e) { @@ -345,7 +359,11 @@ public class BookUtil { @Override public void onFault(String errorMsg) { //失败 - Log.d(TAG,"error on get sitRule: "+errorMsg); + Log.e(TAG,"error on get sitRule: "+errorMsg); + siteRuleRetryCnt++; + if(siteRuleRetryCnt mChapters.size()){ - Log.d(TAG, String.format(" prepare book getChapterNo ,chapterNo %s, getChapters().size() %s " ,chapterNo , mChapters.size()) ); - chapterNo =1; + Log.d(TAG, String.format(" prepare book getChapterNo ,chapterNo %s, getChapters().size() %s ,mChangeChapId %s" ,chapterNo , mChapters.size(),mChangeChapId) ); + if(mChangeChapId>0){ + return mChangeChapId; + } + // chapterNo=1; } - Log.d(TAG, String.format(" prepare book getChapterNo ,chapterNo %s, getChapters().size() %s " ,chapterNo , mChapters.size()) ); + chapterNo = chapterNo<=0 ?1 :chapterNo; + + Log.d(TAG, String.format(" prepare book getChapterNo ,chapterNo %s, getChapters().size() %s " ,chapterNo , mChapters.size()) ); return chapterNo; } @@ -409,16 +433,13 @@ public class BookUtil { 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; - } + this.muluRetryCount=0; this.downloadStatus = DownloadStatus.notStart; chaptDownStatus.clear(); chaptCache.clear(); - + // isDownloadChapt =false; mChangeChapId = chapId; mChangeTitle =chapTitle; for (Site site:mNovelSites.getSites() ) { @@ -443,8 +464,8 @@ public class BookUtil { } - public String getSite() { - return mSite !=null? mSite.getDomain():""; + public Site getSite() { + return mSite !=null? mSite :new Site(); } public boolean chaptCached(int num) { @@ -465,34 +486,67 @@ public class BookUtil { return; } if (result) { - Log.d(TAG, "changing Source:successed get chapters for " + mSite.getDomain() ); + Log.d(TAG, String.format("changing Source: target domain %s chaptId %s, chapt title %s,mChangeChapId %s " + ,domain,chapId,chapTitle,mChangeChapId) ); int chId=chapterNo; String title =""; + mChangeChapId = mChangeChapId >=1 ?mChangeChapId :1;//TODO: mChangeChapId 换源时不要变 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)) { + if(title.equals(mChangeTitle) || title.contains(mChangeTitle) || mChangeTitle.contains(title)) { 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()); + // 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; + title = mChangeTitle; break; } i++; } + + if (!title.equals(mChangeTitle)) { + i = 1; + for (Chapter chapter : mChapters) { + // Log.d(TAG, "changing Source: finding chapter " + i + ":" + chapter.getChapterName()); + if (chapter.getChapterName().contains(mChangeTitle)) { + Log.d(TAG, "changing Source:successed find chapter by original title " + i + ":" + mChangeTitle); + chId = i; + title = chapter.getChapterName(); + break; + } + i++; + } + } + + if (!title.contains(mChangeTitle)) { + i = 1; + for (Chapter chapter : mChapters) { + // Log.d(TAG, "changing Source: finding chapter " + i + ":" + chapter.getChapterName()); + if (mChangeTitle.contains(chapter.getChapterName())) { + Log.d(TAG, "changing Source:successed find chapter by original title " + i + ":" + mChangeTitle); + chId = i; + title = chapter.getChapterName(); + 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); - + mChangeChapId=0; Toast.makeText(mContext,"换源成功",Toast.LENGTH_LONG).show(); }else{ Log.d(TAG, "changing Source: failed " ); @@ -541,7 +595,7 @@ public class BookUtil { * @param chapId * @param chapTitle */ - public void changeSourceNewThread(String domain,int chapId,String 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); @@ -568,7 +622,7 @@ public class BookUtil { }.start(); - /* + *//* while(isChangeSource){ try { Thread.sleep(50); @@ -584,10 +638,10 @@ public class BookUtil { Log.d(TAG, "changing Source: to get site rule" ); getSiteRule(); } - }.start();*/ + }.start();*//* } - +*/ enum MuluStatus{ isDownloading, isDone, @@ -652,7 +706,7 @@ int muluRetryCount =0; Log.e(TAG, "prepare book loadChapts---- failed: ", e); Log.d(TAG, String.format("prepare book loadChapts---- failed %s 目录 from %s", mNovel.getName(), url)); - handler.sendEmptyMessage(3); + // handler.sendEmptyMessage(3); //TODO 如果是取消了访问,则返回 if (e.toString().contains("closed") || e.getMessage().contains("Canceled")) { @@ -663,16 +717,24 @@ int muluRetryCount =0; } mMuluStatus = MuluStatus.failed; - if (muluRetryCount < Constants.retryCnt) { + if (muluRetryCount < Constants.muluRetryCnt) { try { - Thread.sleep(50); + long sleeptime =500; + if(mSiteRule!=null) { + sleeptime = mSiteRule.getMiniInterval4AccessChapter(); + } + Thread.sleep(sleeptime); + } catch (InterruptedException e1) { e1.printStackTrace(); } muluRetryCount++; Log.d(TAG,String.format("prepare book loadChapts----failed, retrying count %s",muluRetryCount )); readChaptersAsync(); + return; } + + Log.d(TAG,String.format("prepare book loadChapts----failed, site count %s",mNovelSites.getSites().length )); if (mNovelSites.getSites().length == 1) { //仅有一个rule,且失败了 // mMuluStatus = MuluStatus.failed; @@ -681,17 +743,33 @@ int muluRetryCount =0; } //try next site + Message msg =Message.obtain(); + msg.what =99; + msg.arg1 =chapterNo; + Bundle bundleData = new Bundle(); for (Site st : mNovelSites.getSites()) { if (!st.getDomain().equals(mSite.getDomain())) { - mSite = st; + //mSite = st; + mNovel.setDomain(st.getDomain()); + + bundleData.putString("siteName", st.getName()); + msg.setData(bundleData); break; } } + // mNovel.setDomain(mSite.getDomain()); muluRetryCount=0; + fileRetryCnt.clear(); + siteRuleRetryCnt=0; + chaptCache.clear(); + + handler.sendMessage(msg); + // handler.sendEmptyMessage(99); // readChaptersAsync(); - getSiteRule(); + + } @@ -701,7 +779,7 @@ int muluRetryCount =0; if(response.code()!=200){ Log.d(TAG,String.format("prepare book loadChapts----failed, %s 目录 from %s,return code %s", mNovel.getName() ,url,response.code() )); - handler.sendEmptyMessage(3); + // handler.sendEmptyMessage(3); mMuluStatus = MuluStatus.failed; if(muluRetryCount index && NetUtil.isNetworkConnected()) { @@ -1397,7 +1498,7 @@ int muluRetryCount =0; } } - + // mChangeChapId =0; int size = (int) file.length(); if (size < 0) { Log.e(TAG, "prepare book chaptChars: Error during reading"+ fileChapterName(index) ); @@ -1464,15 +1565,15 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte return ; } long startTime= new Date().getTime(); - Log.d(TAG,String.format("loadChaptContent----start download %s from %s", chapter.getChapterName() ,url )); + Log.d(TAG,String.format("prepare book loadChaptContent----start download %s from %s", chapter.getChapterName() ,url )); + + // setDownloadFlag(false); - setDownloadFlag(false); - Log.d( TAG,String.format("loadChaptContent isDownloadChapt: %s",isDownloadChapt)); JSONObject siteJson = new JSONObject(); siteJson.put("chapterContentRegex", mSiteRule.getChapterContentRegex()); siteJson.put("chapterContentDumpRegex", mSiteRule.getChapterContentDumpRegex()); - Request request = getTagRequest(url, 0); + Request request = getTagRequest(url, -1); HttpMethods.getOkClient().newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { @@ -1486,8 +1587,8 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte chaptDownStatus.put(index,DownloadStatus.failure); - setDownloadFlag(true); - Log.d( TAG,String.format("prepare book loadChaptContent fail, isDownloadChapt: %s",isDownloadChapt)); + // setDownloadFlag(true); + Log.d( TAG,String.format("prepare book loadChaptContent fail, isDownloadChapt: %s",false)); e.printStackTrace(); // throw new RuntimeException("Error during writing " + fileChapterName( index)); } @@ -1499,22 +1600,27 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte if (body != null ) { if(response.code()!=200){ Log.d(TAG, "prepare book loadChaptContent----network failure returnCode " + response.code()); - setDownloadFlag(true); + // setDownloadFlag(true); chaptDownStatus.put(index,DownloadStatus.failure); - Log.d( TAG,String.format("prepare book loadChaptContent error %s ,isDownloadChapt: %s", response.code(),isDownloadChapt)); + Log.d( TAG,String.format("prepare book loadChaptContent error %s ,isDownloadChapt: %s", response.code(),false)); handler.sendEmptyMessage(1); return; } try { - Charset charset = body.contentType().charset(); + /* 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()); + if(TextUtils.isEmpty(bodyStr)){ + Log.d( TAG,String.format("prepare book loadChaptContent %s isEmpty,retry....", index, Thread.currentThread().getName())); + chaptDownStatus.put(index,DownloadStatus.failure); + return; + } String title = chapter.getChapterName(); String chapterContent = title+ "\n" + NovelParseUtil.getChapterContent(bodyStr, siteJson); char[] buf = chapterContent.toCharArray(); @@ -1527,7 +1633,7 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte writer.close(); Log.d( TAG,String.format("prepare book loadChaptContent file created: %s, thread %s", file.getPath(), Thread.currentThread().getName())); handler.sendEmptyMessage(123); - setDownloadFlag(true); + // setDownloadFlag(true); } catch (IOException | JSONException e) { e.printStackTrace(); Log.e(TAG, "onResponse: prepare book error ",e ); @@ -1539,16 +1645,17 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte body.close(); handler.sendEmptyMessage(123); - setDownloadFlag(true); + // setDownloadFlag(true); } chapter.setNovelId(mNovel.getId()); chapter.setChapterPath(fileChapterName(index)); + chapter.setDomain(mSite.getDomain()); if(chapter.getId()>0) { chapter.update(chapter.getId()); }else{ chapter.save(); } - setDownloadFlag(true); + //setDownloadFlag(true); chaptDownStatus.put(index,DownloadStatus.success); 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() )); @@ -1570,18 +1677,26 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte Request.Builder builder = new Request.Builder() .tag(mNovel.getNovelId()) //标记 请求的tag,切换小说或离开小说界面(BookActivity) 时 取消未执行完毕的 此tag的所有请求 .url(url) - .removeHeader("Pragma") - .header("Cache-Control", "public, max-age=" + maxAge) + .removeHeader("Pragma"); - .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") + for(int i=0;i0) { + builder. header("Cache-Control", "public, max-age=" + maxAge); + } return builder.build(); } diff --git a/zhuike/src/main/java/com/novelbook/android/utils/ChangeSource.java b/zhuike/src/main/java/com/novelbook/android/utils/ChangeSource.java index db01bd5..863d6bd 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/ChangeSource.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/ChangeSource.java @@ -2,4 +2,5 @@ package com.novelbook.android.utils; public interface ChangeSource { public void changeChapter(int chapNum); + public void changeSource(String domainName,String domain,int chapId,String chapTitle); } diff --git a/zhuike/src/main/java/com/novelbook/android/utils/CommonUtil.java b/zhuike/src/main/java/com/novelbook/android/utils/CommonUtil.java index d303779..1425a0e 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/CommonUtil.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/CommonUtil.java @@ -457,6 +457,17 @@ public class CommonUtil { return days; } + public static String getFileName() { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + String date = format.format(new Date(System.currentTimeMillis())); + return date;// 2012年10月03日 23:41:31 + } + + public static String getDateEN() { + SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String date1 = format1.format(new Date(System.currentTimeMillis())); + return date1;// 2012-10-03 23:41:31 + } /* public static boolean isNavigationBarShow(){ diff --git a/zhuike/src/main/java/com/novelbook/android/utils/Constants.java b/zhuike/src/main/java/com/novelbook/android/utils/Constants.java index c8699c6..1d67a68 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/Constants.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/Constants.java @@ -20,6 +20,7 @@ public class Constants { //public static List lstProgress=null; public static String[] lstProgress={"连载中","已完本","新书"}; public static int retryCnt =10; + public static int muluRetryCnt =3; // public static List lstProgress=null; public static boolean showDialogOnUi =true; public static boolean showDialogOnUiPage =false; diff --git a/zhuike/src/main/java/com/novelbook/android/utils/ImageUtil.java b/zhuike/src/main/java/com/novelbook/android/utils/ImageUtil.java index 9c95e07..988684e 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/ImageUtil.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/ImageUtil.java @@ -11,6 +11,6 @@ public class ImageUtil { public static MyImageLoader loader = new MyImageLoader(); public static void loadImage(Context context, String url, ImageView imageView){ loader.displayImage(context, NetUtil.getCoverUrl(url), imageView); - Log.d(TAG,"loading image url: " + NetUtil.getCoverUrl(url)); + //Log.i(TAG,"loading image url: " + NetUtil.getCoverUrl(url)); } } diff --git a/zhuike/src/main/java/com/novelbook/android/utils/LogcatHelper.java b/zhuike/src/main/java/com/novelbook/android/utils/LogcatHelper.java new file mode 100644 index 0000000..0c5b503 --- /dev/null +++ b/zhuike/src/main/java/com/novelbook/android/utils/LogcatHelper.java @@ -0,0 +1,162 @@ +package com.novelbook.android.utils; + + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; + +import android.content.Context; +import android.os.Environment; + +/** + * log日志统计保存 + * + * @author way + * + */ + +public class LogcatHelper { + + private static LogcatHelper INSTANCE = null; + private static String PATH_LOGCAT; + private LogDumper mLogDumper = null; + private int mPId; + + /** + * + * 初始化目录 + * + * */ + public void init(Context context) { + if (Environment.getExternalStorageState().equals( + Environment.MEDIA_MOUNTED)) {// 优先保存到SD卡中 + PATH_LOGCAT = Environment.getExternalStorageDirectory() + .getAbsolutePath() + File.separator + "novelLog"; + } else {// 如果SD卡不存在,就保存到本应用的目录下 + PATH_LOGCAT = context.getFilesDir().getAbsolutePath() + + File.separator + "novelLog"; + } + File file = new File(PATH_LOGCAT); + if (!file.exists()) { + file.mkdirs(); + } + } + + public static LogcatHelper getInstance(Context context) { + if (INSTANCE == null) { + INSTANCE = new LogcatHelper(context); + } + return INSTANCE; + } + + private LogcatHelper(Context context) { + init(context); + mPId = android.os.Process.myPid(); + } + + public void start() { + if (mLogDumper == null) + mLogDumper = new LogDumper(String.valueOf(mPId), PATH_LOGCAT); + mLogDumper.start(); + } + + public void stop() { + if (mLogDumper != null) { + mLogDumper.stopLogs(); + mLogDumper = null; + } + } + + private class LogDumper extends Thread { + + private Process logcatProc; + private BufferedReader mReader = null; + private boolean mRunning = true; + String cmds = null; + private String mPID; + private FileOutputStream out = null; + + public LogDumper(String pid, String dir) { + mPID = pid; + try { + out = new FileOutputStream(new File(dir, "Novel-" + + CommonUtil.getFileName() + ".log")); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + /** + * + * 日志等级:*:v , *:d , *:w , *:e , *:f , *:s + * + * 显示当前mPID程序的 E和W等级的日志. + * + * */ + + // cmds = "logcat *:e *:w | grep \"(" + mPID + ")\""; + // cmds = "logcat | grep \"(" + mPID + ")\"";//打印所有日志信息 + // cmds = "logcat -s way";//打印标签过滤信息 + // cmds = "logcat *:e *:i | grep \"(" + mPID + ")\""; + cmds = "logcat *:D | grep \"(" + mPID + ")\""; + + } + + public void stopLogs() { + mRunning = false; + } + + @Override + public void run() { + try { + logcatProc = Runtime.getRuntime().exec(cmds); + mReader = new BufferedReader(new InputStreamReader( + logcatProc.getInputStream()), 1024); + String line = null; + while (mRunning && (line = mReader.readLine()) != null) { + if (!mRunning) { + break; + } + if (line.length() == 0) { + continue; + } + if (out != null && line.contains(mPID)) { + out.write((CommonUtil.getDateEN() + " " + line + "\n") + .getBytes()); + } + } + + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (logcatProc != null) { + logcatProc.destroy(); + logcatProc = null; + } + if (mReader != null) { + try { + mReader.close(); + mReader = null; + } catch (IOException e) { + e.printStackTrace(); + } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + out = null; + } + + } + + } + + } + +} \ No newline at end of file diff --git a/zhuike/src/main/java/com/novelbook/android/utils/MyImageLoader.java b/zhuike/src/main/java/com/novelbook/android/utils/MyImageLoader.java index 8f1d539..b6169d5 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/MyImageLoader.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/MyImageLoader.java @@ -1,16 +1,20 @@ package com.novelbook.android.utils; +import android.app.Application; import android.content.Context; import android.util.Log; import android.widget.ImageView; import com.bumptech.glide.Glide; +import com.novelbook.android.MyApp; +import com.novelbook.android.R; public class MyImageLoader extends com.youth.banner.loader.ImageLoader { @Override public void displayImage(Context context, Object path, ImageView imageView) { try { - Glide.with(context).load((String) path).into(imageView); + + Glide.with(MyApp.applicationContext).load((String) path).error(R.drawable.googleg_standard_color_18).into(imageView); }catch (Exception e){ Log.e("MyImageLoader", "displayImage: ",e ); } 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 e9f78a8..b545fb1 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/NovelParseUtil.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/NovelParseUtil.java @@ -75,13 +75,13 @@ public class NovelParseUtil { String chapterUrlRegexOnMulu = siteJson.getString("chapterUrlRegexOnMulu"); String chapterUrlPattern = siteJson.getString("chapterUrlPattern"); - Log.d(TAG, "getChaptersMap: chapterUrlRegexOnMulu: " + chapterUrlRegexOnMulu); + //Log.i(TAG, "getChaptersMap: chapterUrlRegexOnMulu: " + chapterUrlRegexOnMulu); Map muluMap = new LinkedHashMap(); String regex = A_Regex; if (!isBlank(chapterUrlRegexOnMulu)) { regex = chapterUrlRegexOnMulu; } - Log.d(TAG, "getChaptersMap: regex: " + regex); + //Log.i(TAG, "getChaptersMap: regex: " + regex); String[] rows = REUtil.matchs(regex, html);; if (rows == null || rows.length == 0) return null; for (int i = rows.length - 1; i >= 0; i--) { @@ -157,12 +157,12 @@ public class NovelParseUtil { return lst; } - public static List getChapters(String url, JSONObject siteJson,String domain,int maxAage,String encoding) throws JSONException { - return getChaptersLst(getChapters(url,siteJson,maxAage,encoding),domain); + public static List getChapters(String url, JSONObject siteJson,String siteName,int maxAage,SiteRule siteRule) throws JSONException { + return getChaptersLst(getChapters(url,siteJson,maxAage,siteRule),siteName); } - public static String[] getChapters(String url, JSONObject siteJson, int maxAge,String encoding) throws JSONException { + public static String[] getChapters(String url, JSONObject siteJson, int maxAge,SiteRule siteRule) throws JSONException { //if (!siteJson.keys().("chapterUrlRegexOnMulu")) return null; String chapterUrlRegexOnMulu = siteJson.getString("chapterUrlRegexOnMulu"); // if(TextUtils.isEmpty(chapterUrlRegexOnMulu)) return null; @@ -172,11 +172,11 @@ public class NovelParseUtil { JSONArray muluArray = siteJson.getJSONArray("chapterUrlRegexOnMulu"); if (muluArray == null || muluArray.length()== 0) return null; - Log.d(TAG, "to get chaps muluArray is null: " +( muluArray ==null) ); + //Log.i(TAG, "to get chaps muluArray is null: " +( muluArray ==null) ); Map context = new HashMap(); context.put("url", url); - Log.d(TAG, "to get chaps url:" + url ); + //Log.i(TAG, "to get chaps url:" + url ); List result = new ArrayList(); // 最外部的大的规则对象 for (int i = 0; i < muluArray.length(); i++) { @@ -184,57 +184,57 @@ public class NovelParseUtil { JSONObject regexsJson = muluArray.getJSONObject(i); String source = regexsJson.getString("source"); source = getContent(source, context); - Log.d(TAG, "to get chaps source:" + source ); + //Log.i(TAG, "to get chaps source:" + source ); if (source.startsWith("html:")) { String _url = source.substring("html:".length()); - source = access(_url,maxAge,encoding); - Log.d(TAG, "to get chaps source:" + source ); + source = access(_url,maxAge,siteRule ); + //Log.i(TAG, "to get chaps source:" + source ); } // 第一次Regex对象 JSONArray regexsArray = regexsJson.getJSONArray("regexs"); - Log.d(TAG, "to get chaps regexsArray.length():" + regexsArray.length() ); + //Log.i(TAG, "to get chaps regexsArray.length():" + regexsArray.length() ); for (int j = 0; j < regexsArray.length(); j++) { JSONObject regexJson = regexsArray.getJSONObject(j); String[] values = null; - Log.d(TAG, "to get chaps regexJson.getBoolean(\"group\"):" + regexJson.getBoolean("group") ); + //Log.i(TAG, "to get chaps regexJson.getBoolean(\"group\"):" + regexJson.getBoolean("group") ); if (regexJson.getBoolean("group")) { values = REUtil.groups(regexJson.getString("regex"), source); } else { values = REUtil.matchs(regexJson.getString("regex"), source); } - Log.d(TAG, "to get chaps values==null? :" + (values==null) ); + //Log.i(TAG, "to get chaps values==null? :" + (values==null) ); for(String s:values){ - Log.d(TAG, "to get chaps value :" + s); + //Log.i(TAG, "to get chaps value :" + s); } if (values != null) context.put(regexJson.getString("name"), values); // String child = siteJson.getString("child"); - Log.d(TAG, "to get chaps siteJson.has(\"child\")? :" + siteJson.has("child")); + //Log.i(TAG, "to get chaps siteJson.has(\"child\")? :" + siteJson.has("child")); if ( regexJson.has("child") ) { // 一般用来做返回结果用的 JSONObject childJson = regexJson.getJSONObject("child"); - Log.d(TAG, "to get chaps childJson :" + childJson.toString()); + //Log.i(TAG, "to get chaps childJson :" + childJson.toString()); for (String value : values) { - Log.d(TAG, "to get chaps value in values :" + value); + //Log.i(TAG, "to get chaps value in values :" + value); String[] values2 = null; - Log.d(TAG, "to get chaps childJson.getBoolean(\"group\") :" + childJson.getBoolean("group")); + //Log.i(TAG, "to get chaps childJson.getBoolean(\"group\") :" + childJson.getBoolean("group")); if (childJson.getBoolean("group")) { values2 = REUtil.groups(childJson.getString("regex"), value); } else { values2 = REUtil.matchs(childJson.getString("regex"), value); } - Log.d(TAG, "to get chaps values2 != null ? :" + (values2 != null)); + //Log.i(TAG, "to get chaps values2 != null ? :" + (values2 != null)); if (values2 != null) { - Log.d(TAG, "to get chaps value in values2 :" + value); + //Log.i(TAG, "to get chaps value in values2 :" + value); context.put(childJson.getString("name"), values2); - Log.d(TAG, "to get chaps siteJson.has(\"output\") :" + siteJson.has("output")); + //Log.i(TAG, "to get chaps siteJson.has(\"output\") :" + siteJson.has("output")); if (childJson.has("output")) { JSONArray outputArray = childJson.getJSONArray("output"); for (int m = 0; m < outputArray.length(); m++) { String v = getContent(outputArray.getString(m), context); - Log.d(TAG, "to get chaps v :" + v); + //Log.i(TAG, "to get chaps v :" + v); if (v != null) result.add(v); } } @@ -243,7 +243,7 @@ public class NovelParseUtil { } } } - Log.d(TAG, "to get chaps <---------------------------- result size :" + result.size()); + //Log.i(TAG, "to get chaps <---------------------------- result size :" + result.size()); return result.toArray(new String[0]); } @@ -276,7 +276,7 @@ public class NovelParseUtil { } - private static String access(String url,int maxAge,String encoding) { + private static String access(String url,int maxAge, SiteRule siteRule) { Request.Builder builder = new Request.Builder() // .tag(mNovel.getNovelId()) //标记 请求的tag,切换小说或离开小说界面(BookActivity) 时 取消未执行完毕的 此tag的所有请求 .url(url) @@ -288,17 +288,20 @@ public class NovelParseUtil { // .header( "Upgrade-Insecure-Requests", "1") // .header("content-type", "text/html; charset=utf-8") ; + for(int i=0;i 0 ? chaptId : 1; final File file = new File(getChapterFileName(chaptId)); if (!file.exists()) { //待下载 @@ -261,26 +262,26 @@ public class PageFactory implements ChangeSource{ if(fileRetryCnt.get(chaptId) > Constants.retryCnt){ mStatus = Status.FAIL; - drawStatus(mBookPageWidget.getCurPage()); - drawStatus(mBookPageWidget.getNextPage()); + drawStatus(); + return chaptPages; } - drawStatus(mBookPageWidget.getCurPage()); - drawStatus(mBookPageWidget.getNextPage()); + drawStatus(); + if( !NetUtil.isNetworkConnected()){ //TODO: 500错误处理 mStatus = Status.NETWORKFAILE; - drawStatus(mBookPageWidget.getCurPage()); - drawStatus(mBookPageWidget.getNextPage()); + drawStatus(); + return chaptPages; } if(getChapters().size()==0 && mBookUtil.muluRetryCount>=Constants.retryCnt) { Log.d(TAG, String.format("prepare book download mulu 失败,重试次数: %s ,thread.name %s",mBookUtil.muluRetryCount,Thread.currentThread().getName() ) ); mBookUtil.muluRetryCount=0; mStatus = Status.FAIL; - drawStatus(mBookPageWidget.getCurPage()); - drawStatus(mBookPageWidget.getNextPage()); + drawStatus(); + return chaptPages; } // showProgressDialog(); @@ -320,8 +321,8 @@ public class PageFactory implements ChangeSource{ super.run(); }}.start(); - drawStatus(mBookPageWidget.getCurPage()); - drawStatus(mBookPageWidget.getNextPage()); + drawStatus(); + return chaptPages; } @@ -336,8 +337,8 @@ public class PageFactory implements ChangeSource{ Log.d(TAG, String.format("prepare book to load chapt %s, cost %s ",chaptId ,new Date().getTime() -starttime) ); mStatus = Status.FINISH; Log.d(TAG, String.format("changing Source prepare book to draw chapter %s, currentChapter %s ",chaptId ,currentChapter ) ); - /* drawStatus(mBookPageWidget.getCurPage()); - drawStatus(mBookPageWidget.getNextPage());*/ + /* drawStatus(); + */ return chaptPages; } @@ -440,22 +441,30 @@ public class PageFactory implements ChangeSource{ progressDialog.dismiss(); } } - public void changeSource(String domain,int chapId,String chapTitle) { + public void changeSource(String domainName,String domain,int chapId,String chapTitle) { + mAd.hideSystemUI(); fileRetryCnt.clear(); chaptMap.clear(); + if(getSite().getDomain().equals(domain)){ //当前源 + Log.d(TAG, "prepare book changing Source: same site with original " + domain); + return; + } + Log.d(TAG, String.format("prepare book changing Source:target site received: name %s, site domain %s ,chapterId %s " ,domainName, domain,chapId)); + mStatus= Status.CHANGESOURCE; + statusChangeSource="正在换源..."; + if(!TextUtils.isEmpty(domainName)) { + statusChangeSource = "前往 " + domainName + " ..."; + } + + drawStatus(); mBookUtil.changeSource(domain, chapId, chapTitle); } - public String getChapterName() { + /* public String getChapterName() { return getChapters().get(currentChapter-1).getChapterName(); - } - - public String getSite() { - return mBookUtil.getSite(); - } - - public String getChapterFileName(int chapid) { - return mBookUtil.fileChapterName(chapid); + }*/ + public Chapter getChapter(){ + return mBookUtil.getChapter(mBookUtil.getChapterNo()); } private static boolean isBusy =false; @@ -471,7 +480,8 @@ public static boolean busy(){ FINISH, FAIL, NETWORKFAILE, - SERVERERROR + SERVERERROR, + CHANGESOURCE ; } public static synchronized PageFactory getInstance(Context context){ @@ -591,10 +601,17 @@ public static boolean busy(){ mLineCount = (int) ((mVisibleHeight - paragrapheight ) / (m_fontSize + lineSpace));// 可显示的行数 // Log.d(TAG,"line count is " + mLineCount +" paragrapheight is " +paragrapheight); } + private void drawStatus(){ + if(mBookPageWidget!=null) { + drawStatus(mBookPageWidget.getCurPage()); + drawStatus(mBookPageWidget.getNextPage()); + } + } private String loadingTxt =""; + private String statusChangeSource ="正在换源..."; private void drawStatus(Bitmap bitmap){ mAd.hideSystemUI(); - mAd.showRefresh(View.VISIBLE); + mAd.showRefresh(View.VISIBLE); String status = ""; switch (mStatus){ case OPENING: @@ -615,6 +632,10 @@ public static boolean busy(){ status = "加载成功"; mAd.showRefresh(View.GONE); break; + case CHANGESOURCE: + status = statusChangeSource; + mAd.showRefresh(View.GONE); + break; } Canvas c = new Canvas(bitmap); @@ -645,6 +666,7 @@ public static boolean busy(){ private long lastPageTime; public void onDraw(Bitmap bitmap,List m_lines,Boolean updateChapter) { mAd.hideSystemUI(); + // mAd.showRefresh(View.GONE); if(m_lines.size()==0){ return; } @@ -684,8 +706,10 @@ public static boolean busy(){ // getNovel().save(); Novel nv = LitePal.find(Novel.class,getNovel().getId()); - Log.d(TAG,String.format("prepare book %s saved lastchapt %s,lastpos %s, db lastchapt %s last pos %s", - getNovel().getId(), currentChapter,currentPage.getBegin(),nv.getLastReadChapt(),nv.getLastReadPos())); + Log.d(TAG,String.format("prepare book %s ,%s isUpdated %s,saved isUpdated %s, saved lastchapt %s,lastpos %s, db lastchapt %s last pos %s", + getNovel().getId(), + getNovel().getName(),getNovel().isUpdated(),nv.isUpdated(), + currentChapter,currentPage.getBegin(),nv.getLastReadChapt(),nv.getLastReadPos())); lastPageTime = new Date().getTime(); @@ -796,13 +820,14 @@ public static boolean busy(){ if(mCurrentChapter!=null){ chapterName = mCurrentChapter.getChapterName(); }else*/ - if (getChapters().size() > 0) + // if (getChapters().size() > 0) { - String chapterName = CommonUtil.subString(getChapterName(),16); + String chapterName =CommonUtil.subString(mBookUtil.getChapter(mBookUtil.getChapterNo()).getChapterName(),16); // CommonUtil.subString(getChapterName(),16); int nChaterWidth = (int) mBatterryPaint.measureText(chapterName) + 1; c.drawText(chapterName, mWidth - marginWidth - nChaterWidth, statusMarginBottom + mBatterryFontSize, mBatterryPaint); } + if(mBookPageWidget!=null) mBookPageWidget.postInvalidate(); } @@ -839,8 +864,14 @@ public static boolean busy(){ Log.d(TAG, "prepare book prePage: to open prepage: "); cancelPage = currentPage; + if(mBookPageWidget==null){ + return; + } onDraw(mBookPageWidget.getCurPage(),currentPage.getLines(),true); currentPage = getPrePage(); + if(mBookPageWidget==null){ + return; + } onDraw(mBookPageWidget.getNextPage(),currentPage.getLines(),true); } @@ -860,7 +891,7 @@ public static boolean busy(){ if (currentPage.getEnd() >= mBookUtil.getBookLen()) { Log.d(TAG,"已经是本章最后一页了"); - m_islastPage =currentChapter == mBookUtil.getChapters().size(); + m_islastPage =currentChapter >= mBookUtil.getChapters().size(); if ( m_islastPage){ Toast.makeText(mContext, "已经是最后一页了", Toast.LENGTH_SHORT).show(); return; @@ -870,10 +901,16 @@ public static boolean busy(){ } // Log.d(TAG, "prepare book nextPage: to open next page: "); cancelPage = currentPage; + if(mBookPageWidget==null){ + return; + } onDraw(mBookPageWidget.getCurPage(),currentPage.getLines(),true); prePage = currentPage; currentPage = getNextPage(); // currentPage = currentChaptPages.get(currentPage.getPageNo()-1); + if(mBookPageWidget==null){ + return; + } onDraw(mBookPageWidget.getNextPage(),currentPage.getLines(),true); Log.d("nextPage","nextPagenext"); } @@ -917,7 +954,9 @@ public static boolean busy(){ * @throws IOException */ public void openBook(Novel book ,Context context) throws IOException { - +if(book==null){ + return; +} if(book.isLocalBook() || mBookUtil==null){ //离线书籍重新初始化加载mBookUtil mBookUtil = new BookUtil(); } @@ -937,8 +976,8 @@ public static boolean busy(){ bookName =getNovel().getName();// FileUtils.getFileName(bookPath); // this.mCurrentChapter = chapter; mStatus = Status.OPENING; - drawStatus(mBookPageWidget.getCurPage()); - drawStatus(mBookPageWidget.getNextPage()); + drawStatus(); + if (bookTask != null && bookTask.getStatus() != AsyncTask.Status.FINISHED){ bookTask.cancel(true); @@ -974,8 +1013,8 @@ public static boolean busy(){ // PageFactory.mStatus = PageFactory.Status.FINISH; }else{ PageFactory.mStatus = PageFactory.Status.FAIL; - drawStatus(mBookPageWidget.getCurPage()); - drawStatus(mBookPageWidget.getNextPage()); + drawStatus(); + Toast.makeText(mContext,"打开书本失败!",Toast.LENGTH_SHORT).show(); } } @@ -1293,6 +1332,9 @@ public static boolean busy(){ //绘制当前页面 public void currentPage(Boolean updateChapter){ // Log.d(TAG, "prepare book currentPage: to open current Page : "); + if(mBookPageWidget==null){ + return; + } onDraw(mBookPageWidget.getCurPage(),currentPage.getLines(),updateChapter); onDraw(mBookPageWidget.getNextPage(),currentPage.getLines(),updateChapter); } @@ -1478,33 +1520,7 @@ public static boolean busy(){ return mStatus; } - public long getBookLen(){ - return mBookUtil.getBookLen(); - } - public TRPage getCurrentPage(){ - return currentPage; - } - - //获取书本的章 - public List getChapters(){ - return mBookUtil.getChapters(); - } - public boolean isReadingCatalogs(){ - return mBookUtil.isReadingCatalogs(); - } - public String getBookPath(){ - return bookPath; - } - public String getBookName(){ - return getNovle().getName(); - } - public Novel getNovle(){ - return mBookUtil.getNovel(); - } - public boolean isWorking(){ - return mBookUtil !=null; - } //是否是第一页 @@ -1565,15 +1581,49 @@ public static boolean busy(){ public interface PageEvent{ void changeProgress(float progress); } - public Novel getNovel(){ + + public void refreshCate(){ + mBookUtil.getChapters().clear(); + mBookUtil.getSiteRule(); + } + public long getBookLen(){ + return mBookUtil.getBookLen(); + } + + public TRPage getCurrentPage(){ + return currentPage; + } + + //获取书本的章 + public List getChapters(){ + return mBookUtil.getChapters(); + } + public boolean isReadingCatalogs(){ + return mBookUtil.isReadingCatalogs(); + } + public String getBookPath(){ + return bookPath; + } + public String getBookName(){ + return getNovel().getName(); + } + public Novel getNovle(){ + return getNovel(); + } + private Novel getNovel(){ if(mBookUtil!=null){ return mBookUtil.getNovel(); } return new Novel(); } - public void refreshCate(){ - mBookUtil.getChapters().clear(); - mBookUtil.getSiteRule(); + public Site getSite(){ + return mBookUtil.getSite(); + } + public boolean isWorking(){ + return mBookUtil !=null; + } + public String getChapterFileName(int chapid) { + return mBookUtil.fileChapterName(chapid); } } diff --git a/zhuike/src/main/java/com/novelbook/android/view/PageWidget.java b/zhuike/src/main/java/com/novelbook/android/view/PageWidget.java index 64a4702..1cead0b 100644 --- a/zhuike/src/main/java/com/novelbook/android/view/PageWidget.java +++ b/zhuike/src/main/java/com/novelbook/android/view/PageWidget.java @@ -118,7 +118,7 @@ public class PageWidget extends View { protected void onDraw(Canvas canvas) { // canvas.drawColor(0xFFAAAAAA); canvas.drawColor(mBgColor); - Log.e("onDraw","isNext:" + isNext + " isRuning:" + isRuning); + // //Log.e("onDraw","isNext:" + isNext + " isRuning:" + isRuning); if (isRuning) { mAnimationProvider.drawMove(canvas); } else { @@ -150,7 +150,7 @@ public class PageWidget extends View { mAnimationProvider.setStartPoint(downX,downY); abortAnimation(); mAnimationProvider.setCancel(false); - Log.e(TAG,"ACTION_DOWN"); + //Log.e(TAG,"ACTION_DOWN"); }else if (event.getAction() == MotionEvent.ACTION_MOVE){ final int slop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); @@ -163,7 +163,7 @@ public class PageWidget extends View { if (isMove){ isMove = true; if (moveX == 0 && moveY ==0) { - Log.e(TAG,"isMove"); + //Log.e(TAG,"isMove"); //判断翻得是上一页还是下一页 if (x - downX >0){ isNext = false; @@ -189,7 +189,7 @@ public class PageWidget extends View { return true; } } - Log.e(TAG,"isNext:" + isNext); + //Log.e(TAG,"isNext:" + isNext); }else{ //判断是否取消翻页 if(mTouchListener.canCancel()) { @@ -213,8 +213,8 @@ public class PageWidget extends View { }else{ noNext=true; } - if(cancelPage) - Log.e(TAG,"cancelPage:" + cancelPage); + // if(cancelPage) + //Log.e(TAG,"cancelPage:" + cancelPage); } moveX = x; @@ -223,7 +223,7 @@ public class PageWidget extends View { this.postInvalidate(); } }else if (event.getAction() == MotionEvent.ACTION_UP){ - Log.e(TAG,"ACTION_UP"); + //Log.e(TAG,"ACTION_UP"); Log.d(TAG, String.format("onTouchEvent:ACTION_UP isMove %s, isbusy %s",isMove,PageFactory.busy())); if (!isMove || PageFactory.busy()){ cancelPage = false; @@ -232,7 +232,7 @@ public class PageWidget extends View { if (mTouchListener != null){ mTouchListener.center(); } - Log.e(TAG,"center"); + //Log.e(TAG,"center"); // mCornerX = 1; // 拖拽点对应的页脚 // mCornerY = 1; // mTouch.x = 0.1f; @@ -266,7 +266,7 @@ public class PageWidget extends View { mTouchListener.cancel(); } - Log.e(TAG, "isNext:" + isNext); + //Log.e(TAG, "isNext:" + isNext); if (!noNext) { isRuning = true; mAnimationProvider.startAnimation(mScroller); diff --git a/zhuike/src/main/res/drawable/ic_refresh_black_24dp.xml b/zhuike/src/main/res/drawable/ic_refresh_black_24dp.xml new file mode 100644 index 0000000..cc2d1e0 --- /dev/null +++ b/zhuike/src/main/res/drawable/ic_refresh_black_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/zhuike/src/main/res/layout/fragment_book_store.xml b/zhuike/src/main/res/layout/fragment_book_store.xml index 863259e..555c603 100644 --- a/zhuike/src/main/res/layout/fragment_book_store.xml +++ b/zhuike/src/main/res/layout/fragment_book_store.xml @@ -17,7 +17,10 @@ app:tl_indicator_width="45dp" app:tl_textSelectColor="@color/tabSelected" app:tl_textUnselectColor="@color/grey" + app:tl_textsize="17sp" + app:tl_textBold="SELECT" app:tl_tab_space_equal ="true" + app:tl_indicator_bounce_enable ="true" /> +