pda/zhuike/.svn/pristine/e5/e5bb63d839534534b62cc82e4ed...

501 lines
17 KiB
Plaintext

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();
}
}