增加配置缓存,优化切换首页的加载速度,支持spider的md5缓存

pull/1/head
Demo 4 years ago
parent b4dfcdaba1
commit 880c516bbb
  1. 2
      .idea/misc.xml
  2. 11
      app/src/main/java/com/github/catvod/crawler/JarLoader.java
  3. 143
      app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
  4. 31
      app/src/main/java/com/github/tvbox/osc/ui/activity/HomeActivity.java
  5. 2
      app/src/main/java/com/github/tvbox/osc/ui/activity/ProjectionPlayActivity.java
  6. 9
      app/src/main/java/com/github/tvbox/osc/ui/activity/SettingActivity.java
  7. 1
      app/src/main/java/com/github/tvbox/osc/ui/dialog/RemoteDialog.java
  8. 52
      app/src/main/java/com/github/tvbox/osc/util/MD5.java
  9. 1
      app/src/main/res/layout/fragment_user_layout.xml
  10. 1
      app/src/main/res/values/dimens.xml

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

@ -26,7 +26,7 @@ public class JarLoader {
*
* @param jarData
*/
public boolean load(byte[] jarData) {
public boolean load(String cache) {
spiders.clear();
proxyFun = null;
boolean success = false;
@ -34,11 +34,6 @@ public class JarLoader {
File cacheDir = new File(App.getInstance().getCacheDir().getAbsolutePath() + "/catvod_csp");
if (!cacheDir.exists())
cacheDir.mkdirs();
String cache = App.getInstance().getCacheDir().getAbsolutePath() + "/catvod_csp.jar";
FileOutputStream fos = new FileOutputStream(cache);
fos.write(jarData);
fos.flush();
fos.close();
classLoader = new DexClassLoader(cache, cacheDir.getAbsolutePath(), null, App.getInstance().getClassLoader());
// make force wait here, some device async dex load
int count = 0;
@ -46,10 +41,10 @@ public class JarLoader {
try {
Class classInit = classLoader.loadClass("com.github.catvod.spider.Init");
if (classInit != null) {
success = true;
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);
@ -59,8 +54,6 @@ public class JarLoader {
}
break;
}
Thread.sleep(200);
} catch (Throwable th) {
th.printStackTrace();

@ -7,6 +7,7 @@ import android.util.Base64;
import com.github.catvod.crawler.JarLoader;
import com.github.catvod.crawler.Spider;
import com.github.tvbox.osc.base.App;
import com.github.tvbox.osc.bean.IJKCode;
import com.github.tvbox.osc.bean.LiveChannel;
import com.github.tvbox.osc.bean.ParseBean;
@ -17,6 +18,7 @@ import com.github.tvbox.osc.server.ControlManager;
import com.github.tvbox.osc.util.AdBlocker;
import com.github.tvbox.osc.util.DefaultConfig;
import com.github.tvbox.osc.util.HawkConfig;
import com.github.tvbox.osc.util.MD5;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@ -27,6 +29,11 @@ import com.orhanobut.hawk.Hawk;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
@ -71,45 +78,22 @@ public class ApiConfig {
return instance;
}
public void loadConfig(LoadConfigCallback callback, Activity activity) {
/*boolean isSourceModeLocal = Hawk.get(HawkConfig.SOURCE_MODE_LOCAL, false);
if (isSourceModeLocal) {
loadConfigLocal(callback, activity);
} else {
loadConfigServer(callback, activity);
}*/
loadConfigServer(callback, activity);
}
public void loadJar(String spider, LoadConfigCallback callback) {
OkGo.<byte[]>get(spider).execute(new AbsCallback<byte[]>() {
@Override
public byte[] convertResponse(okhttp3.Response response) {
try {
return response.body().bytes();
} catch (Throwable th) {
return null;
}
}
@Override
public void onFinish() {
super.onFinish();
public void loadConfig(boolean useCache, LoadConfigCallback callback, Activity activity) {
String apiUrl = Hawk.get(HawkConfig.API_URL, "");
if (apiUrl.isEmpty()) {
callback.error("-1");
return;
}
File cache = new File(App.getInstance().getFilesDir().getAbsolutePath() + "/" + MD5.encode(apiUrl));
if (useCache && cache.exists()) {
try {
parseJson(apiUrl, cache);
callback.success();
return;
} catch (Throwable th) {
th.printStackTrace();
}
@Override
public void onSuccess(Response<byte[]> response) {
if (response != null && response.body() != null) {
jarLoader.load(response.body());
}
}
});
}
private void loadConfigServer(LoadConfigCallback callback, Activity activity) {
String apiUrl = Hawk.get(HawkConfig.API_URL, "");
}
String apiFix = apiUrl;
if (apiUrl.startsWith("clan://")) {
apiFix = clanToAddress(apiUrl);
@ -119,7 +103,21 @@ public class ApiConfig {
@Override
public void onSuccess(Response<String> response) {
try {
String json = response.body();
parseJson(apiUrl, response.body());
try {
File cacheDir = cache.getParentFile();
if (!cacheDir.exists())
cacheDir.mkdirs();
if (cache.exists())
cache.delete();
FileOutputStream fos = new FileOutputStream(cache);
fos.write(json.getBytes("UTF-8"));
fos.flush();
fos.close();
} catch (Throwable th) {
th.printStackTrace();
}
callback.success();
} catch (Throwable th) {
th.printStackTrace();
@ -130,6 +128,15 @@ public class ApiConfig {
@Override
public void onError(Response<String> response) {
super.onError(response);
if (cache.exists()) {
try {
parseJson(apiUrl, cache);
callback.success();
return;
} catch (Throwable th) {
th.printStackTrace();
}
}
callback.error("拉取配置失败");
}
@ -148,11 +155,71 @@ public class ApiConfig {
});
}
public void loadJar(String spider, LoadConfigCallback callback) {
String[] urls = spider.split(";md5;");
String jarUrl = urls[0];
String md5 = urls.length > 1 ? urls[1].trim() : "";
File cache = new File(App.getInstance().getFilesDir().getAbsolutePath() + "/csp.jar");
if (!md5.isEmpty()) {
if (cache.exists() && MD5.getFileMd5(cache).equalsIgnoreCase(md5)) {
if (jarLoader.load(cache.getAbsolutePath())) {
callback.success();
} else {
callback.error("");
}
return;
}
}
OkGo.<File>get(jarUrl).execute(new AbsCallback<File>() {
@Override
public File convertResponse(okhttp3.Response response) throws Throwable {
File cacheDir = cache.getParentFile();
if (!cacheDir.exists())
cacheDir.mkdirs();
if (cache.exists())
cache.delete();
FileOutputStream fos = new FileOutputStream(cache);
fos.write(response.body().bytes());
fos.flush();
fos.close();
return cache;
}
@Override
public void onSuccess(Response<File> response) {
if (response.body().exists()) {
if (jarLoader.load(response.body().getAbsolutePath())) {
callback.success();
} else {
callback.error("");
}
} else {
callback.error("");
}
}
});
}
private void parseJson(String apiUrl, File f) throws Throwable {
System.out.println("从本地缓存加载" + f.getAbsolutePath());
BufferedReader bReader = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8"));
StringBuilder sb = new StringBuilder();
String s = "";
while ((s = bReader.readLine()) != null) {
sb.append(s + "\n");
}
bReader.close();
parseJson(apiUrl, sb.toString());
}
private void parseJson(String apiUrl, String jsonStr) {
JsonObject infoJson = new Gson().fromJson(jsonStr, JsonObject.class);
// spider
spider = DefaultConfig.safeJsonString(infoJson, "spider", "");
spider = spider.split(";md5;")[0];
// 远端站点源
for (JsonElement opt : infoJson.get("sites").getAsJsonArray()) {
JsonObject obj = (JsonObject) opt;

@ -8,6 +8,8 @@ import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.View;
@ -93,12 +95,20 @@ public class HomeActivity extends BaseActivity {
return R.layout.activity_home;
}
boolean useCacheConfig = false;
@Override
protected void init() {
EventBus.getDefault().register(this);
ControlManager.get().startServer();
initView();
initViewModel();
useCacheConfig = false;
Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) {
Bundle bundle = intent.getExtras();
useCacheConfig = bundle.getBoolean("useCache", false);
}
initData();
}
@ -237,6 +247,7 @@ public class HomeActivity extends BaseActivity {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Toast.makeText(HomeActivity.this, "jar加载成功", Toast.LENGTH_SHORT).show();
initData();
}
}, 50);
@ -249,12 +260,19 @@ public class HomeActivity extends BaseActivity {
@Override
public void error(String msg) {
jarInitOk = true;
mHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(HomeActivity.this, "jar加载失败", Toast.LENGTH_SHORT).show();
}
});
}
});
}
return;
}
ApiConfig.get().loadConfig(new ApiConfig.LoadConfigCallback() {
ApiConfig.get().loadConfig(useCacheConfig, new ApiConfig.LoadConfigCallback() {
AlertDialog dialog = null;
@Override
@ -283,6 +301,17 @@ public class HomeActivity extends BaseActivity {
@Override
public void error(String msg) {
if (msg.equalsIgnoreCase("-1")) {
mHandler.post(new Runnable() {
@Override
public void run() {
dataInitOk = true;
jarInitOk = true;
initData();
}
});
return;
}
mHandler.post(new Runnable() {
@Override
public void run() {

@ -16,8 +16,6 @@ import com.github.tvbox.osc.util.HawkConfig;
import com.github.tvbox.osc.util.PlayerHelper;
import com.orhanobut.hawk.Hawk;
import java.util.Map;
/**
* @author pj567
* @date :2021/3/5

@ -1,6 +1,7 @@
package com.github.tvbox.osc.ui.activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.View;
@ -187,7 +188,13 @@ public class SettingActivity extends BaseActivity {
!currentApi.equals(Hawk.get(HawkConfig.API_URL, "")) ||
!homeSourceSort.equals(newHomeSourceSort)) {
AppManager.getInstance().finishAllActivity();
jumpActivity(HomeActivity.class);
if (currentApi.equals(Hawk.get(HawkConfig.API_URL, ""))) {
Bundle bundle = new Bundle();
bundle.putBoolean("useCache", true);
jumpActivity(HomeActivity.class, bundle);
} else {
jumpActivity(HomeActivity.class);
}
} else {
super.onBackPressed();
}

@ -11,7 +11,6 @@ import androidx.annotation.IdRes;
import com.github.tvbox.osc.R;
import com.github.tvbox.osc.server.ControlManager;
import com.github.tvbox.osc.server.RemoteServer;
import com.github.tvbox.osc.ui.tv.QRCodeGen;
/**

@ -4,6 +4,9 @@ import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@ -31,7 +34,7 @@ public class MD5 {
try {
MD5.sDigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
Log.e("获取MD5信息摘要失败" , e.getMessage());
Log.e("获取MD5信息摘要失败", e.getMessage());
}
}
@ -49,10 +52,13 @@ public class MD5 {
* @return md5值
*/
public static String encode(String res) {
byte[] strTemp = res.getBytes();
return encode(strTemp);
}
private static String encode(byte[] bytes) {
try {
byte[] strTemp = res.getBytes();
sDigest.update(strTemp);
sDigest.update(bytes);
byte[] md = sDigest.digest();
int j = md.length;
char str[] = new char[j * 2];
@ -68,15 +74,45 @@ public class MD5 {
}
}
public static String getFileMd5(File f) {
StringBuffer sb = new StringBuffer("");
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] buffer = new byte[4096];
FileInputStream fis = new FileInputStream(f);
int len = 0;
while ((len = fis.read(buffer)) != -1) {
md.update(buffer, 0, len);
}
fis.close();
byte b[] = md.digest();
int d;
for (int i = 0; i < b.length; i++) {
d = b[i];
if (d < 0) {
d = b[i] & 0xff;
}
if (d < 16)
sb.append("0");
sb.append(Integer.toHexString(d));
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
/**
* MD5加码 生成32位md5码
*/
public static String string2MD5(String inStr) {
if (sDigest == null) {
Log.e("MD5","MD5信息摘要初始化失败");
Log.e("MD5", "MD5信息摘要初始化失败");
return null;
} else if (TextUtils.isEmpty(inStr)) {
Log.e("MD5","参数strSource不能为空");
Log.e("MD5", "参数strSource不能为空");
return null;
}
char[] charArray = inStr.toCharArray();
@ -104,10 +140,10 @@ public class MD5 {
*/
public static String encrypt(final String strSource) {
if (sDigest == null) {
Log.e("MD5","MD5信息摘要初始化失败");
Log.e("MD5", "MD5信息摘要初始化失败");
return null;
} else if (TextUtils.isEmpty(strSource)) {
Log.e("MD5","参数strSource不能为空");
Log.e("MD5", "参数strSource不能为空");
return null;
}
try {
@ -117,7 +153,7 @@ public class MD5 {
String strEncrypt = new String(encryptBytes, "utf-8");
return strEncrypt.substring(0, strEncrypt.length() - 1); // 截断Base64产生的换行符
} catch (UnsupportedEncodingException e) {
Log.e("MD5","加密模块暂不支持此字符集合" + e);
Log.e("MD5", "加密模块暂不支持此字符集合" + e);
}
return null;
}

@ -25,6 +25,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="@dimen/vs_25_"
android:clipChildren="false"
android:clipToPadding="false"
android:focusable="false"

@ -19,6 +19,7 @@
<dimen name="vs_4_">-4mm</dimen>
<dimen name="vs_20_">-20mm</dimen>
<dimen name="vs_25_">-25mm</dimen>
<dimen name="vs_60_">-60mm</dimen>
<dimen name="vs_0">0mm</dimen>

Loading…
Cancel
Save