Add jar loader

pull/1/head
FongMi 4 years ago
parent a6344e5722
commit c794f090f7
  1. 21
      app/src/main/java/com/fongmi/bear/net/Callback.java
  2. 5
      app/src/main/java/com/fongmi/bear/ui/BaseActivity.java
  3. 4
      app/src/main/java/com/fongmi/bear/ui/HomeActivity.java
  4. 2
      app/src/main/java/com/fongmi/bear/ui/SettingActivity.java
  5. 63
      app/src/main/java/com/fongmi/bear/ui/SplashActivity.java
  6. 55
      app/src/main/java/com/fongmi/bear/utils/FileUtil.java
  7. 76
      app/src/main/java/com/github/catvod/crawler/Spider.java
  8. 4
      app/src/main/java/com/github/catvod/crawler/SpiderNull.java
  9. 65
      app/src/main/java/com/github/catvod/loader/JarLoader.java
  10. 49
      app/src/main/res/layout/activity_splash.xml
  11. 1
      app/src/main/res/values-zh-rCN/strings.xml
  12. 1
      app/src/main/res/values-zh-rTW/strings.xml
  13. 2
      app/src/main/res/values/colors.xml
  14. 1
      app/src/main/res/values/strings.xml
  15. 2
      app/src/main/res/values/styles.xml

@ -1,7 +1,26 @@
package com.fongmi.bear.net;
public abstract class Callback {
import androidx.annotation.NonNull;
import java.io.File;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Response;
public abstract class Callback implements okhttp3.Callback {
public void onResponse(String result) {
}
public void onResponse(File file) {
}
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
}
}

@ -1,5 +1,6 @@
package com.fongmi.bear.ui;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
@ -22,6 +23,10 @@ public abstract class BaseActivity extends AppCompatActivity {
initEvent();
}
protected Activity getActivity() {
return this;
}
protected void initView() {
}

@ -12,7 +12,7 @@ public class HomeActivity extends BaseActivity {
private ActivityHomeBinding binding;
public static void newInstance(Activity activity) {
public static void start(Activity activity) {
activity.startActivity(new Intent(activity, HomeActivity.class));
activity.finish();
}
@ -25,7 +25,7 @@ public class HomeActivity extends BaseActivity {
@Override
protected void initView() {
if (App.get().getConfig() == null) {
SettingActivity.newInstance(this);
SettingActivity.start(this);
} else {
}

@ -17,7 +17,7 @@ public class SettingActivity extends BaseActivity {
private ActivitySettingBinding binding;
public static void newInstance(Activity activity) {
public static void start(Activity activity) {
activity.startActivity(new Intent(activity, SettingActivity.class));
}

@ -1,43 +1,80 @@
package com.fongmi.bear.ui;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.SuppressLint;
import android.os.Handler;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.viewbinding.ViewBinding;
import com.fongmi.bear.App;
import com.fongmi.bear.bean.Config;
import com.fongmi.bear.databinding.ActivitySplashBinding;
import com.fongmi.bear.net.Callback;
import com.fongmi.bear.net.Task;
import com.fongmi.bear.net.OKHttp;
import com.fongmi.bear.utils.FileUtil;
import com.fongmi.bear.utils.Prefers;
import com.github.catvod.loader.JarLoader;
import java.io.File;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Request;
import okhttp3.Response;
@SuppressLint("CustomSplashScreen")
public class SplashActivity extends BaseActivity {
private ActivitySplashBinding binding;
@Override
protected ViewBinding getBinding() {
return ActivitySplashBinding.inflate(getLayoutInflater());
return binding = ActivitySplashBinding.inflate(getLayoutInflater());
}
@Override
protected void initView() {
String url = Prefers.getString("url");
if (url.isEmpty()) openHome();
else Task.create(getCallback()).run(url);
binding.title.animate().alpha(1).setDuration(2000).setListener(onAnimationEnd()).start();
}
private Callback getCallback() {
return new Callback() {
private AnimatorListenerAdapter onAnimationEnd() {
return new AnimatorListenerAdapter() {
@Override
public void onResponse(String result) {
App.get().setConfig(Config.objectFrom(result));
openHome();
public void onAnimationEnd(Animator animation) {
binding.title.setVisibility(View.GONE);
binding.progress.animate().alpha(1).setDuration(500).start();
binding.info.animate().alpha(1).setDuration(500).start();
checkUrl();
}
};
}
private void openHome() {
new Handler().postDelayed(() -> HomeActivity.newInstance(this), 500);
private void checkUrl() {
String url = Prefers.getString("url");
if (url.isEmpty()) HomeActivity.start(getActivity());
else getConfig(url);
}
private void getConfig(String url) {
OKHttp.get().client().newCall(new Request.Builder().url(url).build()).enqueue(new Callback() {
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
Config config = Config.objectFrom(response.body().string());
App.get().setConfig(config);
loadJar(config.getSpider());
}
});
}
private void loadJar(String url) {
FileUtil.download(url, new Callback() {
@Override
public void onResponse(File file) {
JarLoader.get().load();
HomeActivity.start(getActivity());
}
});
}
}

@ -0,0 +1,55 @@
package com.fongmi.bear.utils;
import androidx.annotation.NonNull;
import com.fongmi.bear.App;
import com.fongmi.bear.net.Callback;
import com.fongmi.bear.net.OKHttp;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Request;
import okhttp3.Response;
public class FileUtil {
public static File getCacheDir() {
return App.get().getExternalCacheDir();
}
public static String getCachePath() {
return getCacheDir().getAbsolutePath();
}
public static File getCacheFile(String fileName) {
return new File(getCacheDir(), fileName);
}
public static File getJar() {
return getCacheFile("spider.jar");
}
public static String getJarPath() {
return getJar().getAbsolutePath();
}
public static void download(String url, Callback callback) {
Request request = new Request.Builder().url(url).build();
OKHttp.get().client().newCall(request).enqueue(new Callback() {
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
callback.onResponse(writeFile(response));
}
});
}
private static File writeFile(Response response) throws IOException {
FileOutputStream fos = new FileOutputStream(getJar());
fos.write(response.body().bytes());
fos.close();
return getJar();
}
}

@ -0,0 +1,76 @@
package com.github.catvod.crawler;
import android.content.Context;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.List;
public abstract class Spider {
public static JSONObject empty = new JSONObject();
public void init(Context context) {
}
public void init(Context context, String extend) {
init(context);
}
/**
* 首頁數據內容
*/
public String homeContent(boolean filter) {
return "";
}
/**
* 首頁最近更新數據 如果上面的homeContent中不包含首頁最近更新視頻的數據 可以使用這個接口返回
*/
public String homeVideoContent() {
return "";
}
/**
* 分類數據
*/
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
return "";
}
/**
* 詳情數據
*/
public String detailContent(List<String> ids) {
return "";
}
/**
* 搜索數據內容
*/
public String searchContent(String key, boolean quick) {
return "";
}
/**
* 播放信息
*/
public String playerContent(String flag, String id, List<String> vipFlags) {
return "";
}
/**
* Webview 解析時使用 可自定義判斷當前加載的 url 是否是視頻
*/
public boolean isVideoFormat(String url) {
return false;
}
/**
* 是否手動檢測 Webview 中加載的 url
*/
public boolean manualVideoCheck() {
return false;
}
}

@ -0,0 +1,4 @@
package com.github.catvod.crawler;
public class SpiderNull extends Spider {
}

@ -0,0 +1,65 @@
package com.github.catvod.loader;
import com.fongmi.bear.App;
import com.fongmi.bear.utils.FileUtil;
import com.github.catvod.crawler.Spider;
import com.github.catvod.crawler.SpiderNull;
import java.io.FileOutputStream;
import dalvik.system.DexClassLoader;
public class JarLoader {
private DexClassLoader classLoader;
private static class Loader {
static volatile JarLoader INSTANCE = new JarLoader();
}
public static JarLoader get() {
return Loader.INSTANCE;
}
public void load(byte[] jarData) {
try {
FileOutputStream fos = new FileOutputStream(FileUtil.getCacheFile("spider.jar"));
fos.write(jarData);
fos.flush();
fos.close();
load();
} catch (Exception e) {
e.printStackTrace();
}
}
public void load() {
try {
classLoader = new DexClassLoader(FileUtil.getJarPath(), FileUtil.getCachePath(), null, App.get().getClassLoader());
int count = 0;
do {
try {
if (classLoader.loadClass("com.github.catvod.spider.Init") != null) {
break;
}
Thread.sleep(200);
} catch (Throwable th) {
th.printStackTrace();
}
count++;
} while (count < 5);
} catch (Exception e) {
e.printStackTrace();
}
}
public Spider getSpider(String key) {
if (classLoader == null) return new SpiderNull();
try {
return (Spider) classLoader.loadClass("com.github.catvod.spider." + key).newInstance();
} catch (Throwable th) {
th.printStackTrace();
}
return new SpiderNull();
}
}

@ -1,4 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:alpha="0"
android:shadowColor="@color/grey_700"
android:shadowDx="2"
android:shadowDy="2"
android:shadowRadius="1"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="32sp"
tools:alpha="1" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:alpha="0"
tools:alpha="1" />
<TextView
android:id="@+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="8dp"
android:alpha="0"
android:text="@string/splash_info"
android:textColor="@color/white"
android:textSize="18sp"
tools:alpha="1" />
</LinearLayout>
</RelativeLayout>

@ -1,6 +1,7 @@
<resources>
<string name="app_name">熊爱影视</string>
<string name="splash_info">正在载入配置</string>
<string name="setting_url">配置接口</string>
<string name="setting_history">历史配置</string>
<string name="dialog_positive">确定</string>

@ -1,6 +1,7 @@
<resources>
<string name="app_name">熊愛影視</string>
<string name="splash_info">正在載入配置</string>
<string name="setting_url">配置接口</string>
<string name="setting_history">歷史配置</string>
<string name="dialog_positive">確定</string>

@ -2,7 +2,7 @@
<color name="primary">@color/black</color>
<color name="primaryDark">@color/black</color>
<color name="accent">@color/blue_500</color>
<color name="accent">@color/white</color>
<color name="black">#000000</color>
<color name="white">#FFFFFF</color>

@ -1,6 +1,7 @@
<resources>
<string name="app_name">BearTV</string>
<string name="splash_info">Loading config</string>
<string name="setting_url">Configure</string>
<string name="setting_history">History</string>
<string name="dialog_positive">OK</string>

@ -6,7 +6,7 @@
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primaryDark</item>
<item name="colorAccent">@color/accent</item>
<item name="colorControlHighlight">@color/accent</item>
<item name="colorControlHighlight">@color/blue_500</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowBackground">@drawable/wallpaper_1</item>
<item name="android:windowTranslucentStatus">true</item>

Loading…
Cancel
Save