You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
JY-TVBoxOS/app/src/main/java/com/github/catvod/crawler/JarLoader.java

212 lines
7.7 KiB

package com.github.catvod.crawler;
import android.content.Context;
import com.github.tvbox.osc.base.App;
import com.github.tvbox.osc.util.MD5;
import com.github.tvbox.osc.util.js.SpiderJS;
import com.lzy.okgo.OkGo;
import org.json.JSONObject;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import dalvik.system.DexClassLoader;
import okhttp3.Response;
public class JarLoader {
private ConcurrentHashMap<String, DexClassLoader> classLoaders = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, Method> proxyMethods = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, Spider> spiders = new ConcurrentHashMap<>();
private volatile String recentJarKey = "";
/**
* 不要在主线程调用我
*
* @param cache
*/
public boolean load(String cache) {
spiders.clear();
recentJarKey = "main";
proxyMethods.clear();
classLoaders.clear();
return loadClassLoader(cache, "main");
}
private boolean loadClassLoader(String jar, String key) {
boolean success = false;
try {
File cacheDir = new File(App.getInstance().getCacheDir().getAbsolutePath() + "/catvod_csp");
if (!cacheDir.exists())
cacheDir.mkdirs();
DexClassLoader classLoader = new DexClassLoader(jar, cacheDir.getAbsolutePath(), null, App.getInstance().getClassLoader());
// make force wait here, some device async dex load
int count = 0;
do {
try {
Class classInit = classLoader.loadClass("com.github.catvod.spider.Init");
if (classInit != null) {
Method method = classInit.getMethod("init", Context.class);
method.invoke(null, App.getInstance());
System.out.println("自定义爬虫代码加载成功!");
success = true;
try {
Class proxy = classLoader.loadClass("com.github.catvod.spider.Proxy");
Method mth = proxy.getMethod("proxy", Map.class);
proxyMethods.put(key, mth);
} catch (Throwable th) {
}
break;
}
Thread.sleep(200);
} catch (Throwable th) {
th.printStackTrace();
}
count++;
} while (count < 5);
if (success) {
classLoaders.put(key, classLoader);
}
} catch (Throwable th) {
th.printStackTrace();
}
return success;
}
private DexClassLoader loadJarInternal(String jar, String md5, String key) {
if (classLoaders.contains(key))
return classLoaders.get(key);
File cache = new File(App.getInstance().getFilesDir().getAbsolutePath() + "/" + key + ".jar");
if (!md5.isEmpty()) {
if (cache.exists() && MD5.getFileMd5(cache).equalsIgnoreCase(md5)) {
loadClassLoader(cache.getAbsolutePath(), key);
return classLoaders.get(key);
}
}
try {
Response response = OkGo.<File>get(jar).execute();
InputStream is = response.body().byteStream();
OutputStream os = new FileOutputStream(cache);
try {
byte[] buffer = new byte[2048];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
try {
is.close();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
loadClassLoader(cache.getAbsolutePath(), key);
return classLoaders.get(key);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
public Spider getSpider(String key, String cls, String ext, String jar) {
if (cls.toLowerCase().endsWith(".js") || cls.toLowerCase().contains(".js?")) {
if (spiders.containsKey(key))
return spiders.get(key);
try {
SpiderJS sp = new SpiderJS(key, cls, ext);
sp.init(App.getInstance(), ext);
spiders.put(key, sp);
return sp;
} catch (Throwable th) {
th.printStackTrace();
}
return null;
}
String clsKey = cls.replace("csp_", "");
String jarUrl = "";
String jarMd5 = "";
String jarKey = "";
if (jar.isEmpty()) {
jarKey = "main";
} else {
String[] urls = jar.split(";md5;");
jarUrl = urls[0];
jarKey = MD5.string2MD5(jarUrl);
jarMd5 = urls.length > 1 ? urls[1].trim() : "";
}
recentJarKey = jarKey;
if (spiders.containsKey(key))
return spiders.get(key);
DexClassLoader classLoader = null;
if (jarKey.equals("main"))
classLoader = classLoaders.get("main");
else {
classLoader = loadJarInternal(jarUrl, jarMd5, jarKey);
}
if (classLoader == null)
return new SpiderNull();
try {
Spider sp = (Spider) classLoader.loadClass("com.github.catvod.spider." + clsKey).newInstance();
sp.init(App.getInstance(), ext);
if (!jar.isEmpty()) {
sp.homeContent(false); // 增加此行 应该可以解决部分写的有问题源的历史记录问题 但会增加这个源的首次加载时间 不需要可以已删掉
}
spiders.put(key, sp);
return sp;
} catch (Throwable th) {
th.printStackTrace();
}
return new SpiderNull();
}
public JSONObject jsonExt(String key, LinkedHashMap<String, String> jxs, String url) {
try {
DexClassLoader classLoader = classLoaders.get("main");
String clsKey = "Json" + key;
String hotClass = "com.github.catvod.parser." + clsKey;
Class jsonParserCls = classLoader.loadClass(hotClass);
Method mth = jsonParserCls.getMethod("parse", LinkedHashMap.class, String.class);
return (JSONObject) mth.invoke(null, jxs, url);
} catch (Throwable th) {
th.printStackTrace();
}
return null;
}
public JSONObject jsonExtMix(String flag, String key, String name, LinkedHashMap<String, HashMap<String, String>> jxs, String url) {
try {
DexClassLoader classLoader = classLoaders.get("main");
String clsKey = "Mix" + key;
String hotClass = "com.github.catvod.parser." + clsKey;
Class jsonParserCls = classLoader.loadClass(hotClass);
Method mth = jsonParserCls.getMethod("parse", LinkedHashMap.class, String.class, String.class, String.class);
return (JSONObject) mth.invoke(null, jxs, name, flag, url);
} catch (Throwable th) {
th.printStackTrace();
}
return null;
}
public Object[] proxyInvoke(Map params) {
try {
Method proxyFun = proxyMethods.get(recentJarKey);
if (proxyFun != null) {
return (Object[]) proxyFun.invoke(null, params);
}
} catch (Throwable th) {
}
return null;
}
}