下载管理
This commit is contained in:
		
							parent
							
								
									664ff9b491
								
							
						
					
					
						commit
						3c4872a58e
					
				|  | @ -12,51 +12,42 @@ | |||
|         android:allowBackup="true" | ||||
|         android:icon="@mipmap/ic_launcher" | ||||
|         android:label="@string/app_name" | ||||
|         android:launchMode="singleInstance" | ||||
|         android:roundIcon="@mipmap/ic_launcher_round" | ||||
|         android:supportsRtl="true" | ||||
|         android:theme="@style/ToolBarTheme" | ||||
|         android:launchMode="singleInstance" | ||||
|         android:usesCleartextTraffic="true"> | ||||
| 
 | ||||
|         <activity android:name=".view.Activitycache"></activity> | ||||
|         <activity | ||||
|             android:name=".Activity_cate_books" | ||||
|             android:label="@string/title_activity_cate_books" | ||||
|             android:launchMode="singleTask" | ||||
|             android:parentActivityName=".activity_cates" | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar" /> | ||||
| 
 | ||||
| 
 | ||||
|         <activity | ||||
|             android:name=".Activity_Search" | ||||
|             android:label="@string/title_activity_cates" | ||||
|             android:launchMode="singleTask" | ||||
|             android:parentActivityName=".Main2Activity" | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar" /> | ||||
| 
 | ||||
|         <activity | ||||
|             android:name=".Activity_paihangbang" | ||||
|             android:label="@string/title_activity_paihangbang" | ||||
|             android:parentActivityName=".Main2Activity" | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar"> | ||||
| 
 | ||||
|         </activity> | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar"></activity> | ||||
|         <activity | ||||
|             android:name=".Activity_ChgSource" | ||||
|             android:label="@string/title_Activity_ChgSource" /> | ||||
|         <activity | ||||
|             android:name=".BookActivity" | ||||
|             android:label="@string/title_activity_book" | ||||
| 
 | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar" /> | ||||
|         <activity | ||||
|             android:name=".ReadActivity" | ||||
|             android:label="@string/app_name" | ||||
| 
 | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar"> | ||||
|         </activity> | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar"></activity> | ||||
|         <activity | ||||
|             android:name=".Main2Activity" | ||||
| 
 | ||||
|             android:launchMode="singleTop" | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar"> | ||||
|             <intent-filter> | ||||
|  | @ -64,28 +55,26 @@ | |||
| 
 | ||||
|                 <category android:name="android.intent.category.LAUNCHER" /> | ||||
|             </intent-filter> | ||||
| 
 | ||||
|         </activity> | ||||
| 
 | ||||
|         <activity | ||||
|             android:name=".FileActivity" | ||||
|             android:label="@string/app_name" | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar"> | ||||
|         </activity> | ||||
| 
 | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar"></activity> | ||||
|         <activity | ||||
|             android:name=".MarkActivity" | ||||
|             android:label="@string/app_name" | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar"> | ||||
|         </activity> | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar"></activity> | ||||
|         <activity | ||||
|             android:name=".filechooser.FileChooserActivity" | ||||
|             android:label="@string/app_name" | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar"> | ||||
|         </activity> | ||||
|         <service android:name="com.novelbook.android.service.ServiceDownload"  android:exported="false"/> | ||||
| 
 | ||||
| 
 | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar"></activity> | ||||
|         <activity | ||||
|             android:name=".Activity_cache" | ||||
|             android:label="@string/title_download" | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar"></activity> | ||||
|         <service | ||||
|             android:name=".service.ServiceDownload" | ||||
|             android:exported="false" /> | ||||
|     </application> | ||||
| 
 | ||||
| </manifest> | ||||
|  | @ -2,7 +2,7 @@ | |||
| <litepal> | ||||
|     <dbname value="book" ></dbname> | ||||
| 
 | ||||
|     <version value="12" ></version> | ||||
|     <version value="15" ></version> | ||||
| 
 | ||||
|     <list> | ||||
|         <mapping class="com.novelbook.android.db.Chapter"></mapping> | ||||
|  |  | |||
|  | @ -0,0 +1,359 @@ | |||
| package com.novelbook.android; | ||||
| 
 | ||||
| import android.app.AlertDialog; | ||||
| import android.content.BroadcastReceiver; | ||||
| import android.content.Context; | ||||
| import android.content.DialogInterface; | ||||
| import android.content.Intent; | ||||
| import android.content.IntentFilter; | ||||
| import android.support.v7.app.AppCompatActivity; | ||||
| import android.os.Bundle; | ||||
| import android.support.v7.widget.GridLayoutManager; | ||||
| import android.support.v7.widget.LinearLayoutManager; | ||||
| import android.support.v7.widget.RecyclerView; | ||||
| import android.util.Log; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.ImageView; | ||||
| import android.widget.ProgressBar; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import com.novelbook.android.Activity_base; | ||||
| import com.novelbook.android.R; | ||||
| import com.novelbook.android.bean.Cataloge; | ||||
| import com.novelbook.android.db.Chapter; | ||||
| import com.novelbook.android.db.DownloadTask; | ||||
| import com.novelbook.android.db.Novel; | ||||
| import com.novelbook.android.service.ServiceDownload; | ||||
| import com.novelbook.android.utils.ImageUtil; | ||||
| 
 | ||||
| import org.litepal.LitePal; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| 
 | ||||
| public class Activity_cache extends Activity_base { | ||||
|     public static final String TAG=Activity_cache.class.getSimpleName(); | ||||
|     @BindView(R.id.recycleView) | ||||
|     RecyclerView mRecyclerView; | ||||
|     private List<DownloadTask> mData; | ||||
|     private CacheAdapter mAdapter; | ||||
|     @Override | ||||
|     public int getLayoutRes() { | ||||
|         return R.layout.activitycache; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected void initViews() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected void setTitle() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected void initData() { | ||||
|         initiDownloadReceiver(); | ||||
|         mData = LitePal.findAll(DownloadTask.class); | ||||
| 
 | ||||
|         mAdapter = new CacheAdapter(this,mData,R.layout.recycle_list_item_cache,new  OnItemClickLitener() { | ||||
|             @Override | ||||
|             public void onItemClick(View view, int position) { | ||||
|                 Novel novel = LitePal.find(Novel.class,mData.get(position).getNovelId()); | ||||
|                 showBookDetail(novel); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void onItemLongClick(View view, int position) | ||||
|             { | ||||
|                 final AlertDialog.Builder normalDialog = | ||||
|                         new AlertDialog.Builder(Activity_cache.this); | ||||
| 
 | ||||
|                 normalDialog.setTitle("删除此下载任务并清除缓存吗"); | ||||
|                 normalDialog.setMessage("确定删除吗?"); | ||||
|                 normalDialog.setPositiveButton("取消", | ||||
|                         new DialogInterface.OnClickListener() { | ||||
|                             @Override | ||||
|                             public void onClick(DialogInterface dialog, int which) { | ||||
| 
 | ||||
|                             } | ||||
|                         }); | ||||
|                 normalDialog.setNegativeButton("删除", | ||||
|                         new DialogInterface.OnClickListener() { | ||||
|                             @Override | ||||
|                             public void onClick(DialogInterface dialog, int which) { | ||||
|                                 DownloadTask cl = mData.get(position); | ||||
|                                 cl.delete(); | ||||
|                                 //   Chapter.deleteByTask(); | ||||
|                                 //TODO:clear cache ? | ||||
| 
 | ||||
| 
 | ||||
|                                 mAdapter.removeData(position); | ||||
| 
 | ||||
|                             } | ||||
|                         }); | ||||
| 
 | ||||
|                 normalDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { | ||||
|                     @Override | ||||
|                     public void onDismiss(DialogInterface dialog) { | ||||
| 
 | ||||
|                     } | ||||
|                 }); | ||||
|                 // 显示 | ||||
|                 normalDialog.show(); | ||||
|                 // mAdapter.removeData(position); | ||||
|             } | ||||
| 
 | ||||
|         }); | ||||
| 
 | ||||
|         mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); | ||||
|         mRecyclerView.setAdapter(mAdapter ); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void fillData() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private IntentFilter filter; | ||||
|     DownloadProcessReceiver receiver; | ||||
|     void initiDownloadReceiver(){ | ||||
|         filter = new IntentFilter("ServiceDownload.ChapterContent.finished"); | ||||
|         filter.addCategory(Intent.CATEGORY_DEFAULT); | ||||
|         receiver = new DownloadProcessReceiver(); | ||||
|     } | ||||
|     class DownloadProcessReceiver extends BroadcastReceiver { | ||||
| 
 | ||||
|         @Override | ||||
|         public void onReceive(Context context, Intent intent){ | ||||
|             int taskId =0; | ||||
|             int progress=0; | ||||
| 
 | ||||
|             if( intent.hasExtra("progress")){ | ||||
|                 progress = intent.getIntExtra("progress",0); | ||||
|             } | ||||
|             if( intent.hasExtra("taskId")){ | ||||
|                 taskId = intent.getIntExtra("taskId",0); | ||||
|             } | ||||
| 
 | ||||
|             Log.d(TAG, String.format("onReceive: taskId %s progress %s ",taskId,progress)); | ||||
|             for(DownloadTask dt : mData){ | ||||
|                 if(taskId == dt.getId()){ | ||||
|                     dt.setFinishedChpats(progress); | ||||
|                     if(dt.getDownSatus()!=DownloadTask.DownStatus.等待下载) { | ||||
|                         dt.setDownSatus(DownloadTask.DownStatus.正在下载); | ||||
|                     } | ||||
|                 }else{ | ||||
|                     if(dt.getDownSatus()!=DownloadTask.DownStatus.正在下载) { | ||||
|                         dt.setDownSatus(DownloadTask.DownStatus.排队中); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             mAdapter.setData(mData); | ||||
| 
 | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
|     private void startDownloadService(int taskId,boolean start) { | ||||
|         Intent serviceIntent =  new Intent(this, ServiceDownload.class); | ||||
|         serviceIntent.putExtra("taskId",taskId); | ||||
|         serviceIntent.putExtra("start",start); | ||||
|         startService(serviceIntent); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected void onResume() { | ||||
|         super.onResume(); | ||||
|         registerReceiver(receiver, filter); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onPause() { | ||||
|         super.onPause(); | ||||
|         unregisterReceiver(receiver); | ||||
|     } | ||||
| 
 | ||||
|     class CacheAdapter extends RecyclerView.Adapter<CacheAdapter.MyViewHolder> { | ||||
|         private final int EMPTY_VIEW = 1; | ||||
|         private final int PROGRESS_VIEW = 2; | ||||
|         private final int IMAGE_VIEW = 3; | ||||
| 
 | ||||
|         private Context context; | ||||
|         private List<DownloadTask> mDatas = new ArrayList<DownloadTask>(); | ||||
|         private OnItemClickLitener mOnItemClickLitener; | ||||
|         private int listItemID; | ||||
| 
 | ||||
|         public CacheAdapter(Context context, List<DownloadTask> mDatas, int listItemID, OnItemClickLitener clickLitener) { | ||||
|             this.context = context; | ||||
|             this.mDatas = mDatas; | ||||
|             this.mOnItemClickLitener = clickLitener; | ||||
|             this.listItemID = listItemID; | ||||
|         } | ||||
| 
 | ||||
|         public CacheAdapter(Context context, OnItemClickLitener clickLitener) { | ||||
|             this.context = context; | ||||
|             this.mOnItemClickLitener = clickLitener; | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public int getItemViewType(int position) { | ||||
|             if (mDatas.size() == 0) { | ||||
|                 return EMPTY_VIEW; | ||||
|             } else if (mDatas.get(position) == null) { | ||||
|                 return PROGRESS_VIEW; | ||||
|             } else { | ||||
|                 return super.getItemViewType(position); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public   CacheAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | ||||
|             CacheAdapter.MyViewHolder holder = new CacheAdapter.MyViewHolder(LayoutInflater.from( | ||||
|                     context).inflate(listItemID, parent, | ||||
|                     false)); | ||||
|             return holder; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         public void setParameters(List<DownloadTask> mDatas, int listItemID) { | ||||
|             this.mDatas = mDatas; | ||||
|             this.listItemID = listItemID; | ||||
|         } | ||||
| 
 | ||||
|         public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener) { | ||||
|             this.mOnItemClickLitener = mOnItemClickLitener; | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public void onBindViewHolder(CacheAdapter.MyViewHolder holder, int position) { | ||||
|             holder.tvTitle.setText(mDatas.get(position).getNovelTitle()); | ||||
|             holder.tvSource.setText(mDatas.get(position).getDomainName()); | ||||
|             boolean finished = mData.get(position).getFinishedChpats() == mData.get(position).getTotalChapts(); | ||||
| 
 | ||||
|            if( mData.get(position).getTotalChapts() >0) { | ||||
|             float progress = mData.get(position).getFinishedChpats() *100/ mData.get(position).getTotalChapts()  ; | ||||
|             holder.tvProgress.setText(String.format("%s/%s",mData.get(position).getFinishedChpats() , mData.get(position).getTotalChapts())); | ||||
| 
 | ||||
|             holder.tvStatus.setText( mData.get(position).getDownSatus() == DownloadTask.DownStatus.正在下载 ?"正在下载" | ||||
|                     : mData.get(position).getDownSatus() == DownloadTask.DownStatus.等待下载? "暂停下载" :"休眠中"); | ||||
| 
 | ||||
|                holder.tvStatus.setText( mData.get(position).getStatus()==0 || mData.get(position).getFinishedChpats()  >=mData.get(position).getTotalChapts() | ||||
|                        ?  holder.tvStatus.getText():"下载完成" ); | ||||
| 
 | ||||
|                holder.tvStatus.setText( mData.get(position).getStatus()==0?  holder.tvStatus.getText():"下载完成" ); | ||||
| 
 | ||||
|             holder.tvStatus.setText( mData.get(position).getDownSatus() == DownloadTask.DownStatus.排队中?"排队中": holder.tvStatus.getText() ); | ||||
| 
 | ||||
|             holder.barProgress.setProgress((int)progress); | ||||
|            } | ||||
|            // holder.imgStart.setVisibility(View.GONE); | ||||
|            int img =  R.mipmap.play; | ||||
|              img =  mData.get(position).getDownSatus() == DownloadTask.DownStatus.正在下载 ? R.mipmap.pause : R.mipmap.play; | ||||
| 
 | ||||
|             holder.imgStart.setImageResource( img); | ||||
|            holder.imgStart.setOnClickListener(new View.OnClickListener() { | ||||
|                @Override | ||||
|                public void onClick(View v) { | ||||
|                    int pos = holder.getLayoutPosition(); | ||||
| 
 | ||||
|                     if(mData.get(position).getDownSatus() != DownloadTask.DownStatus.正在下载) { | ||||
|                         startDownloadService(mData.get(pos).getId(),true); | ||||
|                         holder.imgStart.setImageResource( R.mipmap.pause); | ||||
|                         mData.get(pos).setDownSatus(DownloadTask.DownStatus.排队中); | ||||
| 
 | ||||
|                     }else{ | ||||
|                         startDownloadService(mData.get(pos).getId(),false); | ||||
|                         holder.imgStart.setImageResource( R.mipmap.play); | ||||
|                         mData.get(pos).setDownSatus(DownloadTask.DownStatus.等待下载); | ||||
|                     } | ||||
|                    mData.get(pos).update( mData.get(pos).getId()); | ||||
| 
 | ||||
| 
 | ||||
|                } | ||||
|            }); | ||||
| 
 | ||||
|             // 如果设置了回调,则设置点击事件 | ||||
|             if (mOnItemClickLitener != null) { | ||||
|                 holder.itemView.setOnClickListener(new View.OnClickListener() { | ||||
|                     @Override | ||||
|                     public void onClick(View v) { | ||||
|                         int pos = holder.getLayoutPosition(); | ||||
|                         mOnItemClickLitener.onItemClick(holder.itemView, pos); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
| 
 | ||||
|             holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { | ||||
|                 @Override | ||||
|                 public boolean onLongClick(View v) { | ||||
|                     int pos = holder.getLayoutPosition(); | ||||
|                     mOnItemClickLitener.onItemLongClick(holder.itemView, pos); | ||||
|                     return false; | ||||
|                 } | ||||
|             }); | ||||
|              | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public int getItemCount() { | ||||
|             return mDatas.size(); | ||||
|         } | ||||
| 
 | ||||
|         public void addData(int position) { | ||||
|             //   mDatas.add(position, "Insert One"); | ||||
|             //    notifyItemInserted(position); | ||||
|         } | ||||
| 
 | ||||
|         public void removeData(int position) { | ||||
|             mDatas.remove(position); | ||||
|             notifyItemRemoved(position); | ||||
|             notifyDataSetChanged(); | ||||
|         } | ||||
| 
 | ||||
|         public void setData(List<DownloadTask> data) { | ||||
|             mData = data; | ||||
|             notifyDataSetChanged(); | ||||
|         } | ||||
| 
 | ||||
|         class MyViewHolder extends RecyclerView.ViewHolder { | ||||
|             @BindView(R.id.tvTitle) | ||||
|             TextView tvTitle; | ||||
|             @BindView(R.id.tvProgress) | ||||
|             TextView tvProgress; | ||||
|             @BindView(R.id.tvStatus) | ||||
|             TextView tvStatus; | ||||
|             @BindView(R.id.barProgress) | ||||
|             ProgressBar barProgress; | ||||
|             @BindView(R.id.imgStart) | ||||
|             ImageView imgStart; | ||||
|             @BindView(R.id.tvSource) | ||||
|             TextView tvSource; | ||||
|             public MyViewHolder(View view) { | ||||
|                 super(view); | ||||
|                 ButterKnife.bind(this, view); | ||||
|                 //tvTitle = (TextView) view.findViewById(R.id.title); | ||||
|                 // tvAuthor = (TextView) view.findViewById(R.id.author); | ||||
| 
 | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     interface OnItemClickLitener | ||||
|     { | ||||
|         void onItemClick(View view, int position); | ||||
| 
 | ||||
|         void onItemLongClick(View itemView, int pos); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | @ -29,9 +29,9 @@ public static String TAG ="com.novelbook.android.paihangbang"; | |||
|     ViewPager mViewpager; | ||||
|     @BindView(R.id.tab_layout) | ||||
|     SlidingTabLayout tabLayout; | ||||
|     public static String EXTR_FN="fn"; | ||||
|     public static String EXTR_TITLE="title"; | ||||
|     public static String EXTR_BANGDAN ="bangdan"; | ||||
|     public static final String EXTR_FN="fn"; | ||||
|     public static final String EXTR_TITLE="title"; | ||||
|     public static final String EXTR_BANGDAN ="bangdan"; | ||||
|     public static final String EXTR_SEARCH ="search"; | ||||
|     public static final String EXTR_HISTORY ="history" ; | ||||
|     private ArrayList<Fragment> mFragments; | ||||
|  |  | |||
|  | @ -353,6 +353,10 @@ public class BookActivity extends   Activity_base { | |||
|                 Toast.makeText(BookActivity.this, "已加入下载队列1", Toast.LENGTH_LONG).show(); | ||||
|             } else if (msg.what == 3) { | ||||
|                 Toast.makeText(BookActivity.this, "获取目录信息失败,下载失败", Toast.LENGTH_LONG).show(); | ||||
|             }else if (msg.what == 4) { | ||||
|                 Toast.makeText(BookActivity.this, String.format("亲,小说《%s》已经缓存完成了", mNovel.getName()), Toast.LENGTH_LONG).show(); | ||||
|             }else if (msg.what == 5) { | ||||
|                 Toast.makeText(BookActivity.this, String.format("亲,小说《%s》已经在缓存队列了,请耐心等待", mNovel.getName()), Toast.LENGTH_LONG).show(); | ||||
|             } | ||||
|             hideProgress(); | ||||
|         } | ||||
|  | @ -420,20 +424,7 @@ public class BookActivity extends   Activity_base { | |||
| 
 | ||||
| 
 | ||||
|        // if (LitePal.where("novelId = ?", mNovel.getId() + "").count("DownloadTask") > 0) { | ||||
|             List<DownloadTask> dts = LitePal.where("novelId = ?", mNovel.getId() + "").limit(1).find(DownloadTask.class); | ||||
|             if (dts.size() > 0) { | ||||
|                 if (dts.get(0).getStatus() == 1) { | ||||
|                     Toast.makeText(this, String.format("亲,小说《%s》已经缓存完成了", mNovel.getName()), Toast.LENGTH_LONG).show(); | ||||
| 
 | ||||
|                 } else { | ||||
|                     Toast.makeText(this, String.format("亲,小说《%s》已经在缓存队列了,请耐心等待", mNovel.getName()), Toast.LENGTH_LONG).show(); | ||||
|                     startDownloadService(dts.get(0).getId()); | ||||
|                     // startService( getSvrIntent()); | ||||
|                 } | ||||
| 
 | ||||
|                 return; | ||||
| 
 | ||||
|             } | ||||
|        // } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -454,16 +445,40 @@ public class BookActivity extends   Activity_base { | |||
|                     handler.sendEmptyMessage(3); | ||||
| 
 | ||||
|                 } else { | ||||
| 
 | ||||
| 
 | ||||
|                     List<DownloadTask> dts = LitePal.where("novelId = ? and domain =?", mNovel.getId() + "",mNovel.getDomain()).limit(1).find(DownloadTask.class); | ||||
|                     if (dts.size() > 0) { | ||||
|                         if (dts.get(0).getStatus() == 1) { | ||||
| 
 | ||||
|                             handler.sendEmptyMessage(4); | ||||
| 
 | ||||
|                         } else { | ||||
|                             handler.sendEmptyMessage(5); | ||||
| 
 | ||||
|                             startDownloadService(dts.get(0).getId()); | ||||
|                             // startService( getSvrIntent()); | ||||
|                         } | ||||
| 
 | ||||
|                         return; | ||||
| 
 | ||||
|                     } | ||||
| 
 | ||||
|                     DownloadTask dt = new DownloadTask(); | ||||
|                     dt.setDomain(mNovel.getDomain()); | ||||
|                     dt.setDomainName(mNovel.getDomainName()); | ||||
|                     dt.setFinishedChpats(0); | ||||
|                     dt.setNovelId(mNovel.getId()); | ||||
|                     dt.setStatus(0); | ||||
|                     dt.setTotalChapts(mNovel.getTotalChapts()); | ||||
|                    // dt.setTotalChapts(mNovel.getChaptCnt()); | ||||
|                     dt.setTotalChapts(pageFactory.getChapters().size()); | ||||
|                     dt.setNovelTitle(mNovel.getName()); | ||||
| 
 | ||||
|                     dt.save(); | ||||
|                     //  LitePal.deleteAll("chapter","novelId=?",mNovel.getId()+""); | ||||
|                     for (Chapter chapter : pageFactory.getChapters()) { | ||||
|                         chapter.setNovelId(mNovel.getId()); | ||||
|                         chapter.setTaskId(dt.getId()); | ||||
|                         chapter.save(); | ||||
|                     } | ||||
|                    startDownloadService(dt.getId()); | ||||
|  |  | |||
|  | @ -31,6 +31,7 @@ import com.novelbook.android.Fragments.Fragment_paihang; | |||
| import com.novelbook.android.netsubscribe.BookSubscribe; | ||||
| import com.novelbook.android.netutils.OnSuccessAndFaultListener; | ||||
| import com.novelbook.android.netutils.OnSuccessAndFaultSub; | ||||
| import com.novelbook.android.service.ServiceDownload; | ||||
| import com.novelbook.android.utils.Config; | ||||
| import com.novelbook.android.utils.Constants; | ||||
| import com.novelbook.android.utils.GsonUtil; | ||||
|  | @ -268,8 +269,10 @@ public class Main2Activity extends Activity_base | |||
|             intent.putExtra(Activity_paihangbang.EXTR_HISTORY,"yes"); | ||||
|             intent.putExtra(Activity_paihangbang.EXTR_TITLE,"我曾经看过的书"); | ||||
|             startActivity(intent); | ||||
|         } else if (id == R.id.nav_slideshow) { | ||||
| 
 | ||||
|         } else if (id == R.id.nav_huancun) { | ||||
|             startDownloadService(); | ||||
|             Intent intent = new Intent(Main2Activity.this,Activity_cache.class); | ||||
|             startActivity(intent); | ||||
|         } else if (id == R.id.nav_manage) { | ||||
| 
 | ||||
|         } else if (id == R.id.nav_share) { | ||||
|  | @ -282,7 +285,11 @@ public class Main2Activity extends Activity_base | |||
|         drawer.closeDrawer(GravityCompat.START); | ||||
|         return true; | ||||
|     } | ||||
|     private void startDownloadService() { | ||||
|         Intent serviceIntent = new Intent(this, ServiceDownload.class); | ||||
| 
 | ||||
|         startService(serviceIntent); | ||||
|     } | ||||
|     private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener | ||||
|             = new BottomNavigationView.OnNavigationItemSelectedListener() { | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,12 +1,17 @@ | |||
| package com.novelbook.android.db; | ||||
| 
 | ||||
| 
 | ||||
| import android.text.TextUtils; | ||||
| 
 | ||||
| import org.litepal.LitePal; | ||||
| import org.litepal.crud.LitePalSupport; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import javax.security.auth.callback.CallbackHandler; | ||||
| 
 | ||||
| 
 | ||||
| public class  Chapter extends LitePalSupport implements Serializable { | ||||
|     private int id; | ||||
|  | @ -19,6 +24,9 @@ public class  Chapter extends LitePalSupport implements Serializable { | |||
|     private String chapterPath; //缓存地址 | ||||
|     private String domain; //目标 site | ||||
|     private int index;//第几章 | ||||
|     private int taskId; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     public static Chapter getChapter(int id, String domain, int chapId) { | ||||
|         // Chapter chapter  =(Chapter) | ||||
|  | @ -37,7 +45,13 @@ public class  Chapter extends LitePalSupport implements Serializable { | |||
|         chapter.setChapterPath(""); | ||||
|         return chapter; | ||||
|     } | ||||
|     public int getTaskId() { | ||||
|         return taskId; | ||||
|     } | ||||
| 
 | ||||
|     public void setTaskId(int taskId) { | ||||
|         this.taskId = taskId; | ||||
|     } | ||||
|     public int getIndex() { | ||||
|         return index; | ||||
|     } | ||||
|  | @ -118,10 +132,18 @@ public class  Chapter extends LitePalSupport implements Serializable { | |||
|         this.chapterPath = chapterPath; | ||||
|     } | ||||
| 
 | ||||
|     public static List<Chapter> getUnCachedChapters(int noveId,String domain ){ | ||||
|     public static List<Chapter> getUnCachedChapters(int taskId){ | ||||
|        //  return LitePal.where("novelId = ? and domain = ? and chapterPath = null" ,noveId+"",domain ) .find(Chapter.class); | ||||
| 
 | ||||
|          return LitePal.where("novelId = ? and domain = ?  " ,noveId+"",domain).find(Chapter.class); | ||||
|         //ist<Chapter> lst = LitePal.where("novelId = ? and domain = ?  " ,noveId+"",domain).find(Chapter.class); | ||||
|         List<Chapter> lst = LitePal.where("taskId= ? " ,taskId+"").find(Chapter.class); | ||||
|         List<Chapter> lstrt = new ArrayList<Chapter>(); | ||||
|         for(Chapter chapter : lst){ | ||||
|             if(TextUtils.isEmpty(chapter.getChapterPath())){ | ||||
|                 lstrt.add(chapter); | ||||
|             } | ||||
|         } | ||||
|         return  lstrt; | ||||
|       //  return LitePal.where("novelId = ? and domain = ?  " ,noveId+"",domain).find(Chapter.class); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,11 +9,38 @@ public class DownloadTask extends LitePalSupport implements Serializable { | |||
| 
 | ||||
|     private int id; | ||||
|     private int novelId; | ||||
|     private String novelTitle; | ||||
|     private String domain; | ||||
|     private String domainName; | ||||
|     @Column( defaultValue = "0") | ||||
|     private int status; //0 未完成 1 完成 | ||||
|     private int totalChapts; | ||||
|     private int finishedChpats; | ||||
|     private DownStatus downSatus =DownStatus.初始状态;//0 队列外 1 队列内 | ||||
| 
 | ||||
|     public DownStatus getDownSatus() { | ||||
|         return downSatus; | ||||
|     } | ||||
| 
 | ||||
|     public void setDownSatus(DownStatus downSatus) { | ||||
|         this.downSatus = downSatus; | ||||
|     } | ||||
| 
 | ||||
|     public String getNovelTitle() { | ||||
|         return novelTitle; | ||||
|     } | ||||
| 
 | ||||
|     public void setNovelTitle(String novelTitle) { | ||||
|         this.novelTitle = novelTitle; | ||||
|     } | ||||
| 
 | ||||
|     public String getDomainName() { | ||||
|         return domainName; | ||||
|     } | ||||
| 
 | ||||
|     public void setDomainName(String domainName) { | ||||
|         this.domainName = domainName; | ||||
|     } | ||||
| 
 | ||||
|     public int getTotalChapts() { | ||||
|         return totalChapts; | ||||
|  | @ -63,6 +90,9 @@ public class DownloadTask extends LitePalSupport implements Serializable { | |||
|         this.status = status; | ||||
|     } | ||||
| 
 | ||||
|     public  static enum DownStatus{ | ||||
|        初始状态,等待下载, 正在下载,排队中,下载完成 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -24,6 +24,7 @@ public class Novel extends LitePalSupport implements Serializable{ | |||
|     private String name; | ||||
|     private String infoUrl; | ||||
|     private String domain; | ||||
|     private String domainName; | ||||
|     private String muluUrl; | ||||
|     private String novelPath; | ||||
|     private long lastReadPos; | ||||
|  | @ -61,7 +62,13 @@ public class Novel extends LitePalSupport implements Serializable{ | |||
|         this.readtime = readtime; | ||||
|     } | ||||
| 
 | ||||
|     public String getDomainName() { | ||||
|         return domainName; | ||||
|     } | ||||
| 
 | ||||
|     public void setDomainName(String domainName) { | ||||
|         this.domainName = domainName; | ||||
|     } | ||||
| 
 | ||||
|     public long getLastVisit() { | ||||
|         return lastVisit; | ||||
|  | @ -127,16 +134,6 @@ public class Novel extends LitePalSupport implements Serializable{ | |||
|         this.progress = progress; | ||||
|     } | ||||
| 
 | ||||
|     public int getTotalChapts() { | ||||
|         return totalChapts; | ||||
|     } | ||||
| 
 | ||||
|     public void setTotalChapts(int totalChapts) { | ||||
|         this.totalChapts = totalChapts; | ||||
|     } | ||||
| 
 | ||||
|     private int totalChapts; | ||||
| 
 | ||||
|      public int getId() { | ||||
|         return id; | ||||
|     } | ||||
|  |  | |||
|  | @ -1,8 +1,11 @@ | |||
| package com.novelbook.android.service; | ||||
| 
 | ||||
| import android.app.IntentService; | ||||
| import android.app.Service; | ||||
| import android.content.Intent; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.os.IBinder; | ||||
| import android.os.Message; | ||||
| import android.text.TextUtils; | ||||
| import android.util.Log; | ||||
|  | @ -15,6 +18,7 @@ import com.novelbook.android.netutils.HttpMethods; | |||
| import com.novelbook.android.utils.BookUtil; | ||||
| 
 | ||||
| import com.novelbook.android.utils.NovelParseUtil; | ||||
| import com.novelbook.android.utils.PageFactory; | ||||
| 
 | ||||
| import org.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
|  | @ -41,7 +45,7 @@ import okhttp3.Response; | |||
| import okhttp3.ResponseBody; | ||||
| 
 | ||||
| 
 | ||||
| public class ServiceDownload extends IntentService { | ||||
| public class ServiceDownload extends Service { | ||||
|     private static final String TAG ="ServiceDownload" ; | ||||
| 
 | ||||
|     private   final String storagePath = BookUtil.storagePath; | ||||
|  | @ -57,9 +61,9 @@ public class ServiceDownload extends IntentService { | |||
|    // public ServiceDownload(String name) { | ||||
|   //      super(name); | ||||
|   //  } | ||||
|     public ServiceDownload() { | ||||
|   /*  public ServiceDownload() { | ||||
|         super("ServiceDownload"); | ||||
|     } | ||||
|     }*/ | ||||
| 
 | ||||
|      private Map<Integer,SiteRule>  siteRuleMap = new HashMap<Integer,SiteRule>()  ;  // key = novelId | ||||
|      private DownloadTask processingTask  ; | ||||
|  | @ -67,6 +71,7 @@ public class ServiceDownload extends IntentService { | |||
|      private int chaptIndex=0; | ||||
| 
 | ||||
|     private Map<Integer ,List<Chapter>> tasksMap = new  ConcurrentHashMap<Integer, List<Chapter>>();// key = taskId | ||||
|     private Map<Integer ,List<Chapter>> tasksMapDone = new  ConcurrentHashMap<Integer, List<Chapter>>();// key = taskId | ||||
| 
 | ||||
|     @Override | ||||
|     public void onCreate() { | ||||
|  | @ -91,18 +96,23 @@ public class ServiceDownload extends IntentService { | |||
| 
 | ||||
| 
 | ||||
|     } | ||||
|     @Override | ||||
|     public int onStartCommand(Intent intent, int flags, int startId){ | ||||
|         // // QLog.getLogger().d( TAG,TAG+"... service NaviSvc onStartCommand.....," ); | ||||
|         onHandleIntent(intent); | ||||
|         // We want this service to continue running until it is explicitly | ||||
|         // stopped, so return sticky. | ||||
| //		return START_NOT_STICKY;		//TODO: checking why can not stop the service. | ||||
|         return START_STICKY; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public void onStart(Intent intent, int startId) { | ||||
|         super.onStart(intent, startId); | ||||
|         Log.d(TAG,"test service onStart"); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int onStartCommand(Intent intent, int flags, int startId) { | ||||
|         Log.d(TAG,"test service onStartCommand"); | ||||
|         return super.onStartCommand(intent, flags, startId); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onDestroy() { | ||||
|  | @ -110,65 +120,197 @@ public class ServiceDownload extends IntentService { | |||
|         super.onDestroy(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public IBinder onBind(Intent intent) { | ||||
|         // TODO Auto-generated method stub | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     private List<DownloadTask> downloadTasks = new ArrayList<DownloadTask>(); | ||||
| 
 | ||||
|     @Override | ||||
|     List<Integer> cancelId =new ArrayList<Integer>(); | ||||
| 
 | ||||
|     protected void onHandleIntent( Intent intent) { | ||||
|         Log.d(TAG,"test service onHandleIntent...begin"); | ||||
|         Log.d(TAG,"ServiceDownload onHandleIntent...begin"); | ||||
| 
 | ||||
|         String key ="taskId"; | ||||
|         int taskId =0; | ||||
| 
 | ||||
|         if(intent.hasExtra(key)){ | ||||
|             taskId=	intent.getExtras().getInt(key); | ||||
|             startNewTask(taskId); | ||||
|             DownloadTask dt = LitePal.find(DownloadTask.class,taskId); | ||||
| 
 | ||||
|             if(intent.hasExtra("start")){ | ||||
|                 if(!intent.getBooleanExtra("start",true)){ | ||||
|                     cancelId.add(taskId); | ||||
|                     for(DownloadTask  t : downloadTasks){ | ||||
|                         if( t.getId() == taskId){ | ||||
|                              t.setDownSatus(DownloadTask.DownStatus.等待下载); | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                     stopTask(taskId); | ||||
| 
 | ||||
|                 }else{ | ||||
|                     boolean newTask = true; | ||||
| 
 | ||||
|                     if(cancelId.contains(taskId)){ | ||||
|                         cancelId.remove(cancelId.indexOf(taskId)); | ||||
|                     } | ||||
|                     for(DownloadTask  t : downloadTasks){ | ||||
|                         if(t.getId() == taskId){ | ||||
|                             newTask =false; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     if(newTask) { | ||||
|                         startNewTask(dt); | ||||
|                     } else { | ||||
| 
 | ||||
|                         for (DownloadTask t : downloadTasks) { | ||||
|                             if (t.getId() == taskId) { | ||||
|                                 t.setDownSatus(DownloadTask.DownStatus.正在下载); | ||||
|                                 break; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     startTask(taskId); | ||||
| 
 | ||||
|                     if(taskIndex==0) { | ||||
| 
 | ||||
|                         //  handler.sendEmptyMessage(1); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|         } | ||||
|         else{ | ||||
|           /*  if(processingTask==null) { | ||||
|             Log.d(TAG,"ServiceDownload  downloadTask size: " +downloadTasks.size()); | ||||
| 
 | ||||
| 
 | ||||
|                 new Thread() { | ||||
| 
 | ||||
|                     @Override | ||||
|                     public void run() { | ||||
|                         List<DownloadTask> tmp = LitePal.findAll(DownloadTask.class); | ||||
| 
 | ||||
|                         if (downloadTasks.size() == 0) { | ||||
|                             taskIndex = 0; | ||||
|                             for (DownloadTask dt : tmp) { | ||||
|                                 startNewTask(dt); | ||||
|                             } | ||||
| 
 | ||||
|                         }else{ | ||||
| 
 | ||||
|                             for (DownloadTask dt : tmp) { | ||||
|                                 boolean exist = false; | ||||
|                                 for(DownloadTask t: downloadTasks){ | ||||
|                                     if(t.getId() == dt.getId()){ | ||||
|                                         exist =true; | ||||
|                                         break; | ||||
|                                     } | ||||
|                                 } | ||||
|                                 if(!exist){ | ||||
|                                     startNewTask(dt); | ||||
|                                 } | ||||
| 
 | ||||
|                             } | ||||
| 
 | ||||
|                         } | ||||
|                         if (taskIndex == 0) { | ||||
|                             startTask(); | ||||
|                             //  handler.sendEmptyMessage(1); | ||||
|                         } | ||||
|                     } | ||||
|                 }.start(); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|           /* | ||||
|              if(processingTask==null) { | ||||
|                 startTask(); | ||||
|             }*/ | ||||
|         } | ||||
|         Log.d(TAG,"test service onHandleIntent...over"); | ||||
|         Log.d(TAG,"ServiceDownload test service onHandleIntent...over"); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     Handler handler = new Handler()  { | ||||
|         @Override | ||||
|         public void handleMessage(Message msg) { | ||||
|             if(msg.what ==1){ | ||||
|        /*     if(msg.what ==1){ | ||||
|                 startTask(); | ||||
|             }else if(msg.what==2){ | ||||
|             }else*/ | ||||
|                 if(msg.what==2){ | ||||
|                 int tIndex = msg.getData().getInt("tIndex"); | ||||
| 
 | ||||
| 
 | ||||
|                 if(tIndex>=downloadTasks.size()) { | ||||
|                     return; | ||||
|                 } | ||||
|                 int taskId = downloadTasks.get(tIndex).getId(); | ||||
|                /* if( downloadTasks.get(taskId).getDownSatus() == DownloadTask.DownStatus.等待下载){ | ||||
|                     return; | ||||
|                 } | ||||
|                 if(tasksMap.get(processingTask.getId())==null){ | ||||
|                     return; | ||||
|                 } | ||||
|                 */ | ||||
| 
 | ||||
|                 if(tasksMap.get(taskId)==null){ | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 Log.d(TAG,String.format("%s start new chapt download---- taskId :%s, chapter count %s,chaptIndex %s",TAG | ||||
|                         , processingTask.getId(), | ||||
|                         tasksMap.get(processingTask.getId()).size(),chaptIndex )); | ||||
| 
 | ||||
|               //  if(taskIndex==tIndex+1){ | ||||
| 
 | ||||
| 
 | ||||
|                         Intent broadcastIntent = new Intent(); | ||||
|                         broadcastIntent.setAction("ServiceDownload.ChapterContent.finished"); | ||||
|                         broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); | ||||
|                 broadcastIntent.putExtra("progress", processingTask.getFinishedChpats()); | ||||
|                         broadcastIntent.putExtra("progress", processingTask.getFinishedChpats()>processingTask.getTotalChapts() ?processingTask.getTotalChapts():processingTask.getFinishedChpats()); | ||||
|                         broadcastIntent.putExtra("novelId", processingTask.getNovelId()); | ||||
|                         broadcastIntent.putExtra("taskId", processingTask.getId()); | ||||
|                         sendBroadcast(broadcastIntent); | ||||
| 
 | ||||
|                //   } | ||||
| 
 | ||||
|                 if( tasksMap.get(processingTask.getId()).size()-1 > chaptIndex){ | ||||
|                 if( tasksMap.get(taskId).size()-1 > chaptIndex){ | ||||
|                     if( downloadTasks.get(tIndex).getDownSatus() == DownloadTask.DownStatus.正在下载) { | ||||
|                         chaptIndex++; | ||||
|                     }else{ | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
|                 }else{ | ||||
|                     Log.d(TAG,String.format("%s task done ---- taskId :%s, chapter count %s,chaptIndex %s",TAG , processingTask.getId(), | ||||
|                             tasksMap.get(processingTask.getId()).size(),chaptIndex )); | ||||
|                       //章节全部处理完毕了 | ||||
| 
 | ||||
|                     if(taskId == processingTask.getId()) { | ||||
|                         int abc = 1; | ||||
|                         abc++; | ||||
|                         if(tasksMap.get(taskId).size() == tasksMapDone.get(taskId).size()) { | ||||
|                             processingTask.setStatus(1); | ||||
|                             processingTask.update(processingTask.getId()); | ||||
| 
 | ||||
|                         tasksMap.remove(processingTask.getId()); //会不会线程冲突? | ||||
| 
 | ||||
|                         startTask(); | ||||
|                           //  tasksMap.remove(processingTask.getId()); //会不会线程冲突? | ||||
|                         } | ||||
| 
 | ||||
|                 doDownloadContent(); | ||||
| 
 | ||||
|                     } | ||||
|                   //startTask(); //auto start next task | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 doDownloadContent(tIndex,chaptIndex); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|  | @ -176,22 +318,67 @@ public class ServiceDownload extends IntentService { | |||
|         }; | ||||
| 
 | ||||
| 
 | ||||
|     private void stopTask(int taskId) { | ||||
| 
 | ||||
|         if(processingTask==null || processingTask.getId()==taskId) { | ||||
|             //startTask();//to start next | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 启动指定task | ||||
|      * @param taskId | ||||
|      */ | ||||
|     private void startTask(int taskId) { | ||||
|         if ( downloadTasks.size()==0){ | ||||
|             return; | ||||
|         } | ||||
|         if(processingTask!=null) { | ||||
|             processingTask.update(processingTask.getId()); | ||||
|         } | ||||
|         taskIndex=0; | ||||
|         for(DownloadTask task : downloadTasks) { | ||||
|             if(task.getId()==taskId) { | ||||
|                 processingTask = task; | ||||
|                 break; | ||||
|             } | ||||
|             taskIndex++; | ||||
|         } | ||||
| 
 | ||||
|         processingTask.setDownSatus(DownloadTask.DownStatus.正在下载); | ||||
|         chaptIndex=0; | ||||
|         doDownloadContent(taskIndex,chaptIndex); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * auto next task | ||||
|      */ | ||||
|     private void startTask() { | ||||
| 
 | ||||
|        if ( downloadTasks.size()==0){ | ||||
|            return; | ||||
|        } | ||||
|         if(processingTask!=null) { | ||||
|             processingTask.update(processingTask.getId()); | ||||
|         } | ||||
| 
 | ||||
|         Log.d(TAG,"ServiceDownload start task to download,index " +taskIndex); | ||||
| 
 | ||||
|         if(downloadTasks.size() <=taskIndex){ | ||||
|             taskIndex=0; | ||||
|             processingTask =null; | ||||
|             Log.d(TAG,"No task to download."); | ||||
|             return; | ||||
|          //   Log.d(TAG,"No task to download."); | ||||
|            // return; | ||||
|         } | ||||
| 
 | ||||
|         processingTask =    downloadTasks.get(taskIndex); | ||||
|       if(processingTask.getDownSatus()== DownloadTask.DownStatus.等待下载){ | ||||
|             taskIndex++; | ||||
|             startTask(); | ||||
|             return; | ||||
|         } | ||||
|         processingTask.setDownSatus(DownloadTask.DownStatus.正在下载); | ||||
|         chaptIndex=0; | ||||
|         doDownloadContent(); | ||||
|         doDownloadContent(taskIndex,chaptIndex); | ||||
|         if(taskIndex < downloadTasks.size()-1){ | ||||
|             taskIndex++; | ||||
|         } | ||||
|  | @ -199,16 +386,20 @@ public class ServiceDownload extends IntentService { | |||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     void doDownloadContent(){ | ||||
| 
 | ||||
|         Log.d(TAG, String.format("ServiceDowload--- taskId: %s ",processingTask.getId())); | ||||
|     void doDownloadContent(int taskIndex,int chaptIndex){ | ||||
|         Message mg = Message.obtain(); | ||||
|         mg.what =2; | ||||
|         Bundle bundleData = new Bundle(); | ||||
|         bundleData.putInt("tIndex", taskIndex); | ||||
|         mg.setData(bundleData); | ||||
|         Log.d(TAG, String.format("ServiceDownload--- taskId: %s ",processingTask.getId())); | ||||
|         List<Chapter> chps = tasksMap.get(processingTask.getId()); | ||||
|         if(chps!=null && chps.size()>0) { | ||||
|         if(chps!=null && chps.size()>0 && chps.size() >chaptIndex) { | ||||
|             Chapter chapter = chps.get(chaptIndex); | ||||
| 
 | ||||
|             if (TextUtils.isEmpty(chapter.getChapterPath())) { | ||||
|                 try { | ||||
|                     ServiceDownload(chapter); | ||||
|                     ServiceDownload(taskIndex,chapter); | ||||
|                 } catch (JSONException e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } catch (InterruptedException e) { | ||||
|  | @ -218,19 +409,19 @@ public class ServiceDownload extends IntentService { | |||
|                 } | ||||
| 
 | ||||
|             } else { | ||||
|                 handler.sendEmptyMessage(2); | ||||
|                 handler.sendMessage(mg); | ||||
|             } | ||||
|         }else{ | ||||
|             handler.sendEmptyMessage(2); | ||||
|             handler.sendMessage(mg); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|       void startNewTask(int taskId){ | ||||
|       void startNewTask(DownloadTask dt){ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         DownloadTask dt = LitePal.find(DownloadTask.class,taskId); | ||||
|         if(dt!=null){ | ||||
|             List<Chapter> chps = Chapter.getUnCachedChapters(dt.getNovelId(),dt.getDomain() ); | ||||
|             List<Chapter> chps = Chapter.getUnCachedChapters(dt.getId()); | ||||
|             if(chps==null || chps.size()==0){ | ||||
|                 return; | ||||
|             } | ||||
|  | @ -243,16 +434,16 @@ public class ServiceDownload extends IntentService { | |||
| 
 | ||||
|                 downloadTasks.add(dt); | ||||
| 
 | ||||
|                 for(DownloadTask tmp: downloadTasks){ | ||||
|               /*  for(DownloadTask tmp: downloadTasks){ | ||||
|                     Log.d(TAG, String.format("test service task list : %s",tmp.getId())); | ||||
|                 } | ||||
|                 }*/ | ||||
| 
 | ||||
| 
 | ||||
|                 tasksMap.put(dt.getId(), chps); | ||||
|                 if(taskIndex==0) { | ||||
|               /*  if(taskIndex==0) { | ||||
|                     startTask(); | ||||
|                   //  handler.sendEmptyMessage(1); | ||||
|                 } | ||||
|                 }*/ | ||||
|             } | ||||
|         } | ||||
|         /* | ||||
|  | @ -268,21 +459,27 @@ public class ServiceDownload extends IntentService { | |||
| 
 | ||||
|         */ | ||||
|     } | ||||
|     private void ServiceDownload( Chapter chapter ) throws JSONException, InterruptedException { | ||||
|     private void ServiceDownload(int taskIndex, Chapter chapter ) throws JSONException, InterruptedException { | ||||
| 
 | ||||
|         int taskID=  downloadTasks.get(taskIndex).getId() ; | ||||
|         int msg =2; | ||||
| 
 | ||||
|         Message mg = Message.obtain(); | ||||
|         mg.what =msg; | ||||
|         Bundle bundleData = new Bundle(); | ||||
|         bundleData.putInt("tIndex", taskIndex); | ||||
|         mg.setData(bundleData); | ||||
|         String url = chapter.getChapterUrl(); | ||||
|         if( TextUtils.isEmpty( url)){ | ||||
|             handler.sendEmptyMessage(msg); | ||||
|           //  handler.sendEmptyMessage(msg); | ||||
|             handler.sendMessage(mg); | ||||
|             return ; | ||||
|         } | ||||
|         long startTime= new Date().getTime(); | ||||
|         Log.d(TAG,String.format("ServiceDowload----start download %s from %s",   chapter.getChapterName()  ,url )); | ||||
|         Log.d(TAG,String.format("ServiceDownload----start download %s from %s",   chapter.getChapterName()  ,url )); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         //  Log.d( "ServiceDowload",String.format("ServiceDowload isDownloadChapt: %s",isDownloadChapt)); | ||||
|         //  Log.d( "ServiceDownload",String.format("ServiceDownload isDownloadChapt: %s",isDownloadChapt)); | ||||
|         JSONObject siteJson = new JSONObject(); | ||||
|         siteJson.put("chapterContentRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentRegex()); | ||||
|         siteJson.put("chapterContentDumpRegex",  siteRuleMap.get(chapter.getNovelId()).getChapterContentDumpRegex()); | ||||
|  | @ -290,10 +487,10 @@ public class ServiceDownload extends IntentService { | |||
|         HttpMethods.getOkClient().newCall(request).enqueue(new Callback() { | ||||
|             @Override | ||||
|             public void onFailure(Call call, IOException e) { | ||||
|                 handler.sendMessage(mg); | ||||
|              //   handler.sendEmptyMessage(msg); | ||||
| 
 | ||||
|                 handler.sendEmptyMessage(msg); | ||||
| 
 | ||||
|                 //  Log.d( "ServiceDowload",String.format("ServiceDowload fail, isDownloadChapt: %s",isDownloadChapt)); | ||||
|                 //  Log.d( "ServiceDownload",String.format("ServiceDownload fail, isDownloadChapt: %s",isDownloadChapt)); | ||||
|                 e.printStackTrace(); | ||||
|                 // throw new RuntimeException("Error during writing " + fileChapterName( index)); | ||||
|             } | ||||
|  | @ -303,11 +500,12 @@ public class ServiceDownload extends IntentService { | |||
|                 ResponseBody body = response.body(); | ||||
|                 if (body != null ) { | ||||
|                     if(response.code()!=200){ | ||||
|                         Log.d(TAG, "ServiceDowload----network failure returnCode " + response.code()); | ||||
|                         Log.d(TAG, "ServiceDownload----network failure returnCode " + response.code()); | ||||
|                         //  setDownloadFlag(true); | ||||
|                         //  chaptDownStatus.put(index, BookUtil.DownloadStatus.failure); | ||||
|                         //   Log.d( "ServiceDowload",String.format("ServiceDowload error %s ,isDownloadChapt: %s",  response.code(),isDownloadChapt)); | ||||
|                         handler.sendEmptyMessage(msg); | ||||
|                         //   Log.d( "ServiceDownload",String.format("ServiceDownload error %s ,isDownloadChapt: %s",  response.code(),isDownloadChapt)); | ||||
|                        // handler.sendEmptyMessage(msg); | ||||
|                         handler.sendMessage(mg); | ||||
|                     return; | ||||
|                     } | ||||
| 
 | ||||
|  | @ -322,7 +520,7 @@ public class ServiceDownload extends IntentService { | |||
|                         final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(chapter)), "utf-8");//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小 | ||||
|                         writer.write(buf); | ||||
|                         writer.close(); | ||||
|                         Log.d( "ServiceDowload",String.format("ServiceDowload file created:  %s",  file.getPath())); | ||||
|                         Log.d( "ServiceDownload",String.format("ServiceDownload file created:  %s",  file.getPath())); | ||||
|                         processingTask.setFinishedChpats(processingTask.getFinishedChpats()+1); | ||||
|                         processingTask.update(processingTask.getId()); | ||||
|                         Thread.sleep(siteRuleMap.get(chapter.getNovelId()).getMiniInterval4AccessChapter()); | ||||
|  | @ -340,11 +538,16 @@ public class ServiceDownload extends IntentService { | |||
| 
 | ||||
|                     chapter.setChapterPath(fileChapterName(chapter)); | ||||
|                     chapter.update(chapter.getId()); | ||||
|                     handler.sendEmptyMessage(msg); | ||||
|                    if(! tasksMapDone.containsKey(taskID)){ | ||||
|                        tasksMapDone.put(taskID,new ArrayList<Chapter>()); | ||||
|                    } | ||||
| 
 | ||||
|                     tasksMapDone.get(taskID).add(chapter); | ||||
| 
 | ||||
|                     handler.sendMessage(mg); | ||||
|                     //setDownloadFlag(true); | ||||
|                     //   chaptDownStatus.put(index, BookUtil.DownloadStatus.success); | ||||
|                     Log.d(TAG,String.format("ServiceDowload---- finished download %s, cost time %s ,content path %s ",  chapter.getChapterName(),  new Date().getTime() -startTime ,chapter.getChapterPath()   )); | ||||
|                     Log.d(TAG,String.format("ServiceDownload---- finished download %s, cost time %s ,content path %s ",  chapter.getChapterName(),  new Date().getTime() -startTime ,chapter.getChapterPath()   )); | ||||
| 
 | ||||
|                 } | ||||
|             } | ||||
|  | @ -370,10 +573,10 @@ public class ServiceDownload extends IntentService { | |||
|             return; | ||||
|         } | ||||
|         long startTime = new Date().getTime(); | ||||
|         Log.d(TAG, String.format("ServiceDowload----start download %s from %s", chapter.getChapterName(), url)); | ||||
|         Log.d(TAG, String.format("ServiceDownload----start download %s from %s", chapter.getChapterName(), url)); | ||||
| 
 | ||||
| 
 | ||||
|         //  Log.d( "ServiceDowload",String.format("ServiceDowload isDownloadChapt: %s",isDownloadChapt)); | ||||
|         //  Log.d( "ServiceDownload",String.format("ServiceDownload isDownloadChapt: %s",isDownloadChapt)); | ||||
|         JSONObject siteJson = new JSONObject(); | ||||
|         siteJson.put("chapterContentRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentRegex()); | ||||
|         siteJson.put("chapterContentDumpRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentDumpRegex()); | ||||
|  | @ -382,10 +585,10 @@ public class ServiceDownload extends IntentService { | |||
|         ResponseBody body = response.body(); | ||||
|         if (body != null) { | ||||
|             if (response.code() != 200) { | ||||
|                 Log.d(TAG, "ServiceDowload----network failure returnCode " + response.code()); | ||||
|                 Log.d(TAG, "ServiceDownload----network failure returnCode " + response.code()); | ||||
|                 //  setDownloadFlag(true); | ||||
|                 //  chaptDownStatus.put(index, BookUtil.DownloadStatus.failure); | ||||
|                 //   Log.d( "ServiceDowload",String.format("ServiceDowload error %s ,isDownloadChapt: %s",  response.code(),isDownloadChapt)); | ||||
|                 //   Log.d( "ServiceDownload",String.format("ServiceDownload error %s ,isDownloadChapt: %s",  response.code(),isDownloadChapt)); | ||||
|                 handler.sendEmptyMessage(msg); | ||||
|                 return; | ||||
|             } | ||||
|  | @ -401,7 +604,7 @@ public class ServiceDownload extends IntentService { | |||
|                 final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(chapter)), "utf-8");//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小 | ||||
|                 writer.write(buf); | ||||
|                 writer.close(); | ||||
|                 Log.d("ServiceDowload", String.format("ServiceDowload file created:  %s", file.getPath())); | ||||
|                 Log.d("ServiceDownload", String.format("ServiceDownload file created:  %s", file.getPath())); | ||||
|                 processingTask.setFinishedChpats(processingTask.getFinishedChpats() + 1); | ||||
|                 processingTask.update(processingTask.getId()); | ||||
|                 Thread.sleep(siteRuleMap.get(chapter.getNovelId()).getMiniInterval4AccessChapter()); | ||||
|  | @ -422,7 +625,7 @@ public class ServiceDownload extends IntentService { | |||
| 
 | ||||
|             //setDownloadFlag(true); | ||||
|             //   chaptDownStatus.put(index, BookUtil.DownloadStatus.success); | ||||
|             Log.d(TAG, String.format("ServiceDowload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() - startTime, chapter.getChapterPath())); | ||||
|             Log.d(TAG, String.format("ServiceDownload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() - startTime, chapter.getChapterPath())); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,500 @@ | |||
| package com.novelbook.android.service; | ||||
| 
 | ||||
| import android.app.IntentService; | ||||
| import android.content.Intent; | ||||
| import android.os.Handler; | ||||
| import android.os.Message; | ||||
| import android.text.TextUtils; | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import com.novelbook.android.db.Chapter; | ||||
| import com.novelbook.android.db.DownloadTask; | ||||
| import com.novelbook.android.db.SiteRule; | ||||
| import com.novelbook.android.netutils.HttpMethods; | ||||
| import com.novelbook.android.utils.BookUtil; | ||||
| import com.novelbook.android.utils.NovelParseUtil; | ||||
| 
 | ||||
| import org.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
| import org.litepal.LitePal; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.FileOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.OutputStreamWriter; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Date; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| import okhttp3.Call; | ||||
| import okhttp3.Callback; | ||||
| import okhttp3.Request; | ||||
| import okhttp3.Response; | ||||
| import okhttp3.ResponseBody; | ||||
| 
 | ||||
| 
 | ||||
| public class ServiceDownloadIntent extends IntentService { | ||||
|     private static final String TAG ="ServiceDownload" ; | ||||
| 
 | ||||
|     private   final String storagePath = BookUtil.storagePath; | ||||
|     private   final String cachedPath = BookUtil.cachedPath; | ||||
|     private   final String chapterPath = BookUtil.chapterPath; | ||||
| 
 | ||||
|     public final String EXTR_TASKID ="taskId"; | ||||
|     public final String EXTR_OFFSET ="offset"; //多线程下载,每个线程取章节偏移数量 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|    // public ServiceDownload(String name) { | ||||
|   //      super(name); | ||||
|   //  } | ||||
|     public ServiceDownloadIntent() { | ||||
|         super("ServiceDownload"); | ||||
|     } | ||||
| 
 | ||||
|      private Map<Integer,SiteRule>  siteRuleMap = new HashMap<Integer,SiteRule>()  ;  // key = novelId | ||||
|      private DownloadTask processingTask  ; | ||||
|      private int taskIndex=0; | ||||
|      private int chaptIndex=0; | ||||
| 
 | ||||
|     private Map<Integer ,List<Chapter>> tasksMap = new  ConcurrentHashMap<Integer, List<Chapter>>();// key = taskId | ||||
| 
 | ||||
|     @Override | ||||
|     public void onCreate() { | ||||
|         super.onCreate(); | ||||
|         Log.d(TAG,"test service onCreate..."); | ||||
| 
 | ||||
|         /* | ||||
|         downloadTasks =LitePal.where("status = ?","0").find(DownloadTask.class); | ||||
|         for(DownloadTask dt :downloadTasks){ | ||||
|             List<Chapter> chps =Chapter.getUnCachedChapters(dt.getNovelId(),dt.getDomain()); | ||||
|             if(chps.size()>0) { | ||||
|                 SiteRule sr = SiteRule.getSiteRuleByDomain(dt.getDomain()); | ||||
|                 siteRuleMap.put(dt.getNovelId(), sr); | ||||
|                 tasksMap.put(dt.getId(), chps); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         for(DownloadTask tmp: downloadTasks){ | ||||
|             Log.d(TAG, String.format("test service task list : %s",tmp.getId())); | ||||
|         } | ||||
|         */ | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
|     @Override | ||||
|     public void onStart(Intent intent, int startId) { | ||||
|         super.onStart(intent, startId); | ||||
|         Log.d(TAG,"test service onStart"); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int onStartCommand(Intent intent, int flags, int startId) { | ||||
|         Log.d(TAG,"test service onStartCommand"); | ||||
|         return super.onStartCommand(intent, flags, startId); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onDestroy() { | ||||
|         Log.d(TAG,"test service onDestroy"); | ||||
|         super.onDestroy(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     private List<DownloadTask> downloadTasks = new ArrayList<DownloadTask>(); | ||||
| 
 | ||||
|     int cancelId =0; | ||||
|     @Override | ||||
|     protected void onHandleIntent( Intent intent) { | ||||
|         Log.d(TAG,"test service onHandleIntent...begin"); | ||||
| 
 | ||||
|         String key ="taskId"; | ||||
|         int taskId =0; | ||||
| 
 | ||||
|         if(intent.hasExtra(key)){ | ||||
|             taskId=	intent.getExtras().getInt(key); | ||||
|             DownloadTask dt = LitePal.find(DownloadTask.class,taskId); | ||||
| 
 | ||||
|             if(intent.hasExtra("start")){ | ||||
|                 if(!intent.getBooleanExtra("start",true)){ | ||||
|                     cancelId = taskId; | ||||
|                     stopTask(taskId); | ||||
|                 }else{ | ||||
|                     startNewTask(dt); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|         } | ||||
|         else{ | ||||
|             if(downloadTasks.size()==0) { | ||||
|                 List<DownloadTask> tmp = LitePal.findAll(DownloadTask.class); | ||||
|                 taskIndex=0; | ||||
|                 for(DownloadTask dt :tmp) { | ||||
|                     startNewTask(dt); | ||||
|                 } | ||||
| 
 | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|           /* | ||||
|              if(processingTask==null) { | ||||
|                 startTask(); | ||||
|             }*/ | ||||
|         } | ||||
|         Log.d(TAG,"test service onHandleIntent...over"); | ||||
|     } | ||||
| 
 | ||||
|     private void stopTask(int taskId) { | ||||
|         for(DownloadTask dt : downloadTasks){ | ||||
|             if(dt.getId() == taskId){ | ||||
|                 dt.setDownSatus(DownloadTask.DownStatus.等待下载); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         startTask(); | ||||
|     } | ||||
| 
 | ||||
|     Handler handler = new Handler()  { | ||||
|         @Override | ||||
|         public void handleMessage(Message msg) { | ||||
|             if(msg.what ==1){ | ||||
|                 startTask(); | ||||
|             }else if(msg.what==2){ | ||||
| 
 | ||||
|                 if( downloadTasks.get(taskIndex).getDownSatus() == DownloadTask.DownStatus.等待下载){ | ||||
|                     return; | ||||
|                 } | ||||
|                 if(tasksMap.get(processingTask.getId())==null){ | ||||
|                     return; | ||||
|                 } | ||||
|                 Log.d(TAG,String.format("%s start new chapt download---- taskId :%s, chapter count %s,chaptIndex %s",TAG | ||||
|                         , processingTask.getId(), | ||||
|                         tasksMap.get(processingTask.getId()).size(),chaptIndex )); | ||||
| 
 | ||||
| 
 | ||||
|                 Intent broadcastIntent = new Intent(); | ||||
|                 broadcastIntent.setAction("ServiceDownload.ChapterContent.finished"); | ||||
|                 broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); | ||||
|                 broadcastIntent.putExtra("progress", processingTask.getFinishedChpats()); | ||||
|                 broadcastIntent.putExtra("novelId", processingTask.getNovelId()); | ||||
|                 broadcastIntent.putExtra("taskId", processingTask.getId()); | ||||
|                 sendBroadcast(broadcastIntent); | ||||
| 
 | ||||
| 
 | ||||
|                 if( tasksMap.get(processingTask.getId()).size()-1 > chaptIndex){ | ||||
| 
 | ||||
|                     chaptIndex++; | ||||
| 
 | ||||
|                 }else{ | ||||
|                     Log.d(TAG,String.format("%s task done ---- taskId :%s, chapter count %s,chaptIndex %s",TAG , processingTask.getId(), | ||||
|                             tasksMap.get(processingTask.getId()).size(),chaptIndex )); | ||||
|                       //章节全部处理完毕了 | ||||
|                         processingTask.setStatus(1); | ||||
|                         processingTask.update(processingTask.getId()); | ||||
| 
 | ||||
|                         tasksMap.remove(processingTask.getId()); //会不会线程冲突? | ||||
| 
 | ||||
|                         startTask(); | ||||
|                 } | ||||
| 
 | ||||
|                 doDownloadContent(); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         }; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     private void startTask() { | ||||
| 
 | ||||
|         if(processingTask!=null) { | ||||
|             processingTask.update(processingTask.getId()); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         if(downloadTasks.size() <=taskIndex){ | ||||
|             processingTask =null; | ||||
|             Log.d(TAG,"No task to download."); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         processingTask =    downloadTasks.get(taskIndex); | ||||
|         if(processingTask.getDownSatus()== DownloadTask.DownStatus.等待下载){ | ||||
|             taskIndex++; | ||||
|             startTask(); | ||||
|             return; | ||||
|         } | ||||
|         processingTask.setDownSatus(DownloadTask.DownStatus.正在下载); | ||||
|         chaptIndex=0; | ||||
|         doDownloadContent(); | ||||
|         if(taskIndex < downloadTasks.size()-1){ | ||||
|             taskIndex++; | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     void doDownloadContent(){ | ||||
| 
 | ||||
|         Log.d(TAG, String.format("ServiceDowload--- taskId: %s ",processingTask.getId())); | ||||
|         List<Chapter> chps = tasksMap.get(processingTask.getId()); | ||||
|         if(chps!=null && chps.size()>0) { | ||||
|             Chapter chapter = chps.get(chaptIndex); | ||||
| 
 | ||||
|             if (TextUtils.isEmpty(chapter.getChapterPath())) { | ||||
|                 try { | ||||
|                     ServiceDownload(chapter); | ||||
|                 } catch (JSONException e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } catch (InterruptedException e) { | ||||
|                     e.printStackTrace(); | ||||
|                // } catch (IOException e) { | ||||
|               //      e.printStackTrace(); | ||||
|                 } | ||||
| 
 | ||||
|             } else { | ||||
|                 handler.sendEmptyMessage(2); | ||||
|             } | ||||
|         }else{ | ||||
|             handler.sendEmptyMessage(2); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|       void startNewTask(DownloadTask dt){ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         if(dt!=null){ | ||||
|             List<Chapter> chps = Chapter.getUnCachedChapters(dt.getId() ); | ||||
|             if(chps==null || chps.size()==0){ | ||||
|                 return; | ||||
|             } | ||||
|             SiteRule siteRule = SiteRule. getSiteRuleByDomain(dt.getDomain()); | ||||
|             if(siteRule==null){ | ||||
|                 //to do get siterule from web | ||||
|                 Log.d(TAG, String.format("没找到site rule: %s",dt.getDomain())); | ||||
|             }else { | ||||
|                 siteRuleMap.put(dt.getNovelId(),siteRule); | ||||
| 
 | ||||
|                 downloadTasks.add(dt); | ||||
| 
 | ||||
|                 for(DownloadTask tmp: downloadTasks){ | ||||
|                     Log.d(TAG, String.format("test service task list : %s",tmp.getId())); | ||||
|                 } | ||||
| 
 | ||||
| 
 | ||||
|                 tasksMap.put(dt.getId(), chps); | ||||
|                 if(taskIndex==0) { | ||||
|                     startTask(); | ||||
|                   //  handler.sendEmptyMessage(1); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         /* | ||||
|         new Thread() { | ||||
| 
 | ||||
|             @Override | ||||
|             public void run() { | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|             } | ||||
|         }.start(); | ||||
| 
 | ||||
|         */ | ||||
|     } | ||||
|     private void ServiceDownload( Chapter chapter ) throws JSONException, InterruptedException { | ||||
| 
 | ||||
|         int msg =2; | ||||
| 
 | ||||
|         String url = chapter.getChapterUrl(); | ||||
|         if( TextUtils.isEmpty( url)){ | ||||
|             handler.sendEmptyMessage(msg); | ||||
|             return ; | ||||
|         } | ||||
|         long startTime= new Date().getTime(); | ||||
|         Log.d(TAG,String.format("ServiceDowload----start download %s from %s",   chapter.getChapterName()  ,url )); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         //  Log.d( "ServiceDowload",String.format("ServiceDowload isDownloadChapt: %s",isDownloadChapt)); | ||||
|         JSONObject siteJson = new JSONObject(); | ||||
|         siteJson.put("chapterContentRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentRegex()); | ||||
|         siteJson.put("chapterContentDumpRegex",  siteRuleMap.get(chapter.getNovelId()).getChapterContentDumpRegex()); | ||||
|         Request request = getTagRequest(url); | ||||
|         HttpMethods.getOkClient().newCall(request).enqueue(new Callback() { | ||||
|             @Override | ||||
|             public void onFailure(Call call, IOException e) { | ||||
| 
 | ||||
|                 handler.sendEmptyMessage(msg); | ||||
| 
 | ||||
|                 //  Log.d( "ServiceDowload",String.format("ServiceDowload fail, isDownloadChapt: %s",isDownloadChapt)); | ||||
|                 e.printStackTrace(); | ||||
|                 // throw new RuntimeException("Error during writing " + fileChapterName( index)); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void onResponse(Call call, Response response){ | ||||
|                 ResponseBody body = response.body(); | ||||
|                 if (body != null ) { | ||||
|                     if(response.code()!=200){ | ||||
|                         Log.d(TAG, "ServiceDowload----network failure returnCode " + response.code()); | ||||
|                         //  setDownloadFlag(true); | ||||
|                         //  chaptDownStatus.put(index, BookUtil.DownloadStatus.failure); | ||||
|                         //   Log.d( "ServiceDowload",String.format("ServiceDowload error %s ,isDownloadChapt: %s",  response.code(),isDownloadChapt)); | ||||
|                         handler.sendEmptyMessage(msg); | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
|                     try { | ||||
|                         String bodyStr = body.string(); | ||||
|                         String title = chapter.getChapterName(); | ||||
|                         String chapterContent = title+ "\n" + NovelParseUtil.getChapterContent(bodyStr, siteJson); | ||||
|                         char[] buf = chapterContent.toCharArray(); | ||||
|                         File file = new File(fileChapterName(chapter)); | ||||
|                         file.createNewFile(); | ||||
| 
 | ||||
|                         final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(chapter)), "utf-8");//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小 | ||||
|                         writer.write(buf); | ||||
|                         writer.close(); | ||||
|                         Log.d( "ServiceDowload",String.format("ServiceDowload file created:  %s",  file.getPath())); | ||||
|                         processingTask.setFinishedChpats(processingTask.getFinishedChpats()+1); | ||||
|                         processingTask.update(processingTask.getId()); | ||||
|                         Thread.sleep(siteRuleMap.get(chapter.getNovelId()).getMiniInterval4AccessChapter()); | ||||
|                         //  setDownloadFlag(true); | ||||
|                     } catch (IOException | JSONException | InterruptedException e) { | ||||
|                         e.printStackTrace(); | ||||
|                         //  throw new RuntimeException("Error during writing " + fileChapterName( index)); | ||||
|                     } | ||||
|                     finally { | ||||
|                         body.close(); | ||||
| 
 | ||||
| 
 | ||||
|                         //  setDownloadFlag(true); | ||||
|                     } | ||||
| 
 | ||||
|                     chapter.setChapterPath(fileChapterName(chapter)); | ||||
|                     chapter.update(chapter.getId()); | ||||
|                     handler.sendEmptyMessage(msg); | ||||
| 
 | ||||
|                     //setDownloadFlag(true); | ||||
|                     //   chaptDownStatus.put(index, BookUtil.DownloadStatus.success); | ||||
|                     Log.d(TAG,String.format("ServiceDowload---- finished download %s, cost time %s ,content path %s ",  chapter.getChapterName(),  new Date().getTime() -startTime ,chapter.getChapterPath()   )); | ||||
| 
 | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 直接 | ||||
|      * @param chapter | ||||
|      * @throws JSONException | ||||
|      * @throws InterruptedException | ||||
| 
 | ||||
| 
 | ||||
|     private void ServiceDownload2( Chapter chapter ) throws IOException, JSONException, InterruptedException { | ||||
| 
 | ||||
|         int msg = 2; | ||||
| 
 | ||||
|         String url = chapter.getChapterUrl(); | ||||
|         if (TextUtils.isEmpty(url)) { | ||||
|             handler.sendEmptyMessage(msg); | ||||
|             return; | ||||
|         } | ||||
|         long startTime = new Date().getTime(); | ||||
|         Log.d(TAG, String.format("ServiceDowload----start download %s from %s", chapter.getChapterName(), url)); | ||||
| 
 | ||||
| 
 | ||||
|         //  Log.d( "ServiceDowload",String.format("ServiceDowload isDownloadChapt: %s",isDownloadChapt)); | ||||
|         JSONObject siteJson = new JSONObject(); | ||||
|         siteJson.put("chapterContentRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentRegex()); | ||||
|         siteJson.put("chapterContentDumpRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentDumpRegex()); | ||||
|         Request request = getTagRequest(url); | ||||
|         Response response = HttpMethods.getOkClient().newCall(request).execute(); | ||||
|         ResponseBody body = response.body(); | ||||
|         if (body != null) { | ||||
|             if (response.code() != 200) { | ||||
|                 Log.d(TAG, "ServiceDowload----network failure returnCode " + response.code()); | ||||
|                 //  setDownloadFlag(true); | ||||
|                 //  chaptDownStatus.put(index, BookUtil.DownloadStatus.failure); | ||||
|                 //   Log.d( "ServiceDowload",String.format("ServiceDowload error %s ,isDownloadChapt: %s",  response.code(),isDownloadChapt)); | ||||
|                 handler.sendEmptyMessage(msg); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             try { | ||||
|                 String bodyStr = body.string(); | ||||
|                 String title = chapter.getChapterName(); | ||||
|                 String chapterContent = title + "\n" + NovelParseUtil.getChapterContent(bodyStr, siteJson); | ||||
|                 char[] buf = chapterContent.toCharArray(); | ||||
|                 File file = new File(fileChapterName(chapter)); | ||||
|                 file.createNewFile(); | ||||
| 
 | ||||
|                 final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(chapter)), "utf-8");//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小 | ||||
|                 writer.write(buf); | ||||
|                 writer.close(); | ||||
|                 Log.d("ServiceDowload", String.format("ServiceDowload file created:  %s", file.getPath())); | ||||
|                 processingTask.setFinishedChpats(processingTask.getFinishedChpats() + 1); | ||||
|                 processingTask.update(processingTask.getId()); | ||||
|                 Thread.sleep(siteRuleMap.get(chapter.getNovelId()).getMiniInterval4AccessChapter()); | ||||
|                 //  setDownloadFlag(true); | ||||
|             } catch (IOException | JSONException | InterruptedException e) { | ||||
|                 e.printStackTrace(); | ||||
|                 //  throw new RuntimeException("Error during writing " + fileChapterName( index)); | ||||
|             } finally { | ||||
|                 body.close(); | ||||
| 
 | ||||
| 
 | ||||
|                 //  setDownloadFlag(true); | ||||
|             } | ||||
| 
 | ||||
|             chapter.setChapterPath(fileChapterName(chapter)); | ||||
|             chapter.update(chapter.getId()); | ||||
|             handler.sendEmptyMessage(msg); | ||||
| 
 | ||||
|             //setDownloadFlag(true); | ||||
|             //   chaptDownStatus.put(index, BookUtil.DownloadStatus.success); | ||||
|             Log.d(TAG, String.format("ServiceDowload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() - startTime, chapter.getChapterPath())); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| */ | ||||
| 
 | ||||
|     protected String fileChapterName(Chapter chapter ) { | ||||
|             return  getChapterPath(chapter.getNovelId()) +chapter.getDomain()+"/"+ chapter.getIndex() ; | ||||
| 
 | ||||
|     } | ||||
|     String getChapterPath(int novelId){ | ||||
|         File file = new File(chapterPath +novelId); | ||||
|         if(!file.exists()){ | ||||
|             file.mkdir(); | ||||
|         } | ||||
|         return  chapterPath +novelId+"/"; | ||||
|     } | ||||
| 
 | ||||
|     private Request getTagRequest(String url) { | ||||
|         return new  Request.Builder() | ||||
|                 .tag(processingTask.getNovelId()) //标记 | ||||
|                 .url(url) | ||||
|                 // .header("User-Agent", "OkHttp Example") | ||||
|                 .build(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | @ -248,6 +248,7 @@ public class BookUtil { | |||
|             file.mkdir(); | ||||
|         } | ||||
|         mNovel.setDomain(mSite.getDomain()); | ||||
|         mNovel.setDomainName(mSite.getName()); | ||||
|         mNovel.setMuluUrl(mSite.getMuluUrl()); | ||||
|         mNovel.update(mNovel.getId()); | ||||
|     } | ||||
|  | @ -818,7 +819,7 @@ int muluRetryCount =0; | |||
|                         if (!st.getDomain().equals(mSite.getDomain())) { | ||||
|                             //mSite = st; | ||||
|                             mNovel.setDomain(st.getDomain()); | ||||
| 
 | ||||
|                             mNovel.setDomainName(mSite.getName()); | ||||
|                             bundleData.putString("siteName", st.getName()); | ||||
|                             msg.setData(bundleData); | ||||
|                             break; | ||||
|  |  | |||
|  | @ -0,0 +1,35 @@ | |||
| <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     android:id="@+id/main_content" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     android:fitsSystemWindows="true" | ||||
|     android:clipToPadding="true" | ||||
|     tools:context=".Activity_cache"> | ||||
| 
 | ||||
|     <android.support.design.widget.AppBarLayout | ||||
|         android:id="@+id/appbar" | ||||
|         style="@style/barLayout"> | ||||
| 
 | ||||
|         <android.support.v7.widget.Toolbar | ||||
|             android:id="@+id/toolbar" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="@dimen/toolbarHeight" | ||||
|             android:background="?attr/colorPrimary" | ||||
|             app:popupTheme="@style/ToolBarTheme.PopupOverlay"> | ||||
| 
 | ||||
|         </android.support.v7.widget.Toolbar> | ||||
| 
 | ||||
|     </android.support.design.widget.AppBarLayout> | ||||
| 
 | ||||
|     <android.support.v7.widget.RecyclerView | ||||
|         android:id="@+id/recycleView" | ||||
|         style="@style/llOutside" | ||||
|         android:layout_marginTop="50dp" | ||||
|         android:divider="@color/list_item_divider" | ||||
|         > | ||||
|     </android.support.v7.widget.RecyclerView> | ||||
| 
 | ||||
| 
 | ||||
| </android.support.design.widget.CoordinatorLayout> | ||||
|  | @ -17,36 +17,37 @@ | |||
|         tools:ignore="UnusedAttribute"> | ||||
| 
 | ||||
|         <LinearLayout | ||||
|             android:clickable="true" | ||||
|             android:id="@+id/llBookdetail" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="100dp" | ||||
|             android:background="@color/white" | ||||
|             android:layout_height="110dp" | ||||
|             android:layout_alignParentBottom="true" | ||||
|             android:paddingStart="100dp" | ||||
|             android:paddingLeft="120dp" | ||||
|             android:background="@color/white" | ||||
|             android:clickable="true" | ||||
|             android:orientation="horizontal" | ||||
|             > | ||||
|             android:paddingStart="105dp" | ||||
|             android:paddingLeft="120dp"> | ||||
| 
 | ||||
|             <LinearLayout | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_gravity="center_vertical" | ||||
|                 android:paddingStart="15dp" | ||||
|                 android:paddingRight="10dp" | ||||
| 
 | ||||
|                 android:layout_gravity="top" | ||||
|                 android:layout_weight="1" | ||||
|                 android:background="@drawable/item_selector" | ||||
|                 android:orientation="vertical"> | ||||
|                 android:orientation="vertical" | ||||
|                 android:paddingStart="15dp" | ||||
|                 android:paddingRight="10dp" | ||||
|                 android:paddingTop="5dp"> | ||||
| 
 | ||||
|                 <TextView | ||||
|                     android:id="@+id/bdTitle" | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:ellipsize="marquee" | ||||
|                     android:text="射雕英雄传" | ||||
|                     android:textColor="@color/colorPrimary" | ||||
|                     android:textSize="16sp" | ||||
|                     android:textStyle="bold" | ||||
|                     android:ellipsize="marquee" | ||||
|                     tools:ignore="HardcodedText,TextViewEdits" /> | ||||
| 
 | ||||
| 
 | ||||
|  | @ -54,18 +55,18 @@ | |||
|                     android:id="@+id/tvAuthor" | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:visibility="visible" | ||||
|                     android:text="金庸" | ||||
|                     android:visibility="visible" | ||||
|                     tools:ignore="HardcodedText" /> | ||||
| 
 | ||||
|                 <TextView | ||||
|                 android:layout_marginTop="2dp" | ||||
|                     android:id="@+id/txtLatestCate" | ||||
|                     style="@style/TextViewDesc" | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="wrap_content" | ||||
|                 android:lines="1" | ||||
|                     android:layout_marginTop="2dp" | ||||
|                     android:ellipsize="end" | ||||
|                     android:lines="1" | ||||
|                     android:text="" | ||||
| 
 | ||||
|                     /> | ||||
|  | @ -89,11 +90,11 @@ | |||
|         <android.support.v7.widget.CardView | ||||
|             android:id="@+id/cardView" | ||||
|             android:layout_width="80dp" | ||||
|             android:layout_height="130dp" | ||||
|             android:layout_marginEnd="14dp" | ||||
|             android:layout_marginRight="14dp" | ||||
|             android:layout_height="100dp" | ||||
|             android:layout_marginStart="20dp" | ||||
|             android:layout_marginLeft="20dp" | ||||
|             android:layout_marginEnd="14dp" | ||||
|             android:layout_marginRight="14dp" | ||||
|             android:layout_marginBottom="5dp" | ||||
|             app:cardBackgroundColor="@color/white" | ||||
|             app:cardCornerRadius="6dp" | ||||
|  |  | |||
|  | @ -0,0 +1,96 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:orientation="horizontal" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="80dp" | ||||
|     android:gravity="center" | ||||
|     android:background="@drawable/item_selector" | ||||
|     android:clickable="true" | ||||
|     android:paddingStart="10dp" | ||||
|     android:layout_weight="1"> | ||||
| 
 | ||||
|     <LinearLayout | ||||
|         android:orientation="vertical" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="match_parent" | ||||
|         android:gravity="center" | ||||
| 
 | ||||
|         android:layout_weight="1"> | ||||
|         <LinearLayout | ||||
|             android:layout_marginTop="5dp" | ||||
|             android:orientation="horizontal" | ||||
|             android:layout_width="match_parent" | ||||
|             android:paddingRight="10dp" | ||||
|             android:layout_height="wrap_content"> | ||||
|         <TextView | ||||
|             android:id="@+id/tvTitle" | ||||
|          style="@style/TextViewNovelTitle" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="20dp" | ||||
|             android:layout_gravity="left" | ||||
|             android:text="射雕英雄传" | ||||
|             android:layout_weight="1" | ||||
|             android:textColor="@color/blacktitle" /> | ||||
|             <TextView | ||||
|                 android:id="@+id/tvStatus" | ||||
|                 android:layout_marginLeft="5dp" | ||||
|                 android:layout_width="wrap_content" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:gravity="right" | ||||
|                 android:textSize="12sp" | ||||
|                 android:text="未知" | ||||
|                 android:textColor="@color/grey" /> | ||||
| 
 | ||||
|         </LinearLayout> | ||||
|         <LinearLayout | ||||
|         android:layout_marginTop="5dp" | ||||
|         android:orientation="horizontal" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|             android:paddingRight="10dp" | ||||
|         > | ||||
|         <TextView | ||||
|             android:id="@+id/tvSource" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:text="-/-" | ||||
|             android:layout_weight="1" | ||||
|             android:textSize="12sp" | ||||
|             android:textColor="@color/blacktitle" /> | ||||
| 
 | ||||
|             <TextView | ||||
|                 android:id="@+id/tvProgress" | ||||
|                 android:layout_width="wrap_content" | ||||
|                 android:layout_height="20dp" | ||||
|                 android:textSize="12sp" | ||||
|                 android:gravity="right" | ||||
|                 android:layout_marginStart="50dp" | ||||
|                 android:text="未知" | ||||
|                 android:textColor="@color/grey" /> | ||||
| 
 | ||||
|     </LinearLayout> | ||||
| 
 | ||||
| 
 | ||||
|         <ProgressBar android:id="@+id/barProgress" | ||||
|             android:layout_width="fill_parent" | ||||
|             android:layout_height="8dp" | ||||
|             android:max="100" | ||||
|             android:paddingTop="5dp" | ||||
|            style="@android:style/Widget.ProgressBar.Horizontal" | ||||
| 
 | ||||
|             /> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     </LinearLayout> | ||||
| 
 | ||||
|     <ImageView | ||||
|         android:clickable="true" | ||||
|         android:id="@+id/imgStart" | ||||
|         android:layout_width="20dp" | ||||
|         android:layout_height="20dp" | ||||
|        android:layout_margin="10dp" | ||||
|         android:src="@mipmap/play" | ||||
|         /> | ||||
| 
 | ||||
| </LinearLayout> | ||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 353 B | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 342 B | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 904 B | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 929 B | 
		Loading…
	
		Reference in New Issue