java
package com.qisyun.sunday.activities;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.qisyun.sunday.AlertDialog;
import com.qisyun.sunday.BaseActivity;
import com.qisyun.sunday.helper.BrowserEngineHelper;
import com.qisyun.sunday.qlog.XLog;
import com.qisyun.sunday.webview.BridgeHandler;
import com.qisyun.sunday.webview.IWebView;
import com.qisyun.sunday.webview.QsyBridge;
import com.qisyun.sunday.webview.WebPlayerFactory;
import com.qisyun.sunday.webview.WebViewClient;
import com.qisyun.sunday.webview.WebViewFactory;
import com.qisyun.sunday.webview.android.AndroidWebView;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class WebViewBaseActivity extends BaseActivity {
// 静态字段
private static final String TAG = "WebViewBaseActivity";
private static final long TIMEOUT_LOADING;
private static Map<String, String> keyMapper;
// 实例字段
private boolean backKeyHasDown;
protected boolean initedWebEngine;
private FrameLayout playerContainer;
protected ViewGroup rootView;
private Runnable timeoutTrigger;
protected IWebView webView;
private FrameLayout webViewContainer;
// 静态初始化块
static {
TimeUnit timeUnit = TimeUnit.SECONDS;
long seconds = 0x3c;
TIMEOUT_LOADING = timeUnit.toMillis(seconds);
Map<String, String> map = new HashMap<>();
map.put(String.valueOf(0x15), "left");
map.put(String.valueOf(0x16), "right");
map.put(String.valueOf(0x13), "up");
map.put(String.valueOf(0x14), "down");
map.put(String.valueOf(0x17), "enter");
map.put(String.valueOf(0x42), "");
keyMapper = map;
}
// 构造函数
public WebViewBaseActivity() {
super();
initedWebEngine = false;
Runnable runnable = new Runnable() {
@Override
public void run() {
// 待实现的超时触发逻辑
}
};
timeoutTrigger = runnable;
backKeyHasDown = false;
}
// 私有方法:将按键事件分发到 JavaScript
private void dispatchKey2Js(ValueCallback<Boolean> valueCallback, String keyCode) {
IWebView webView = this.webView;
if (webView == null) {
valueCallback.onReceiveValue(Boolean.valueOf(false));
return;
}
long currentTimeMillis = SystemClock.uptimeMillis();
IWebView webView1 = this.webView;
QsyBridge qsyBridge = webView1.getQsyBridge();
String bridgeName = qsyBridge.getName();
Object[] objects = new Object[4];
objects[0] = bridgeName;
objects[1] = Boolean.valueOf(true);
objects[2] = Boolean.valueOf(true);
objects[3] = keyCode;
String format = String.format("%s && %s.onKeydown && %s.onKeydown('%s')", objects);
webView.callJs(format, new ValueCallback() {
@Override
public void onReceiveValue(Object value) {
// 待实现回调逻辑
}
});
}
// 私有方法:处理按键按下事件
private void handleKeyDown(int keyCode) {
Map<String, String> keyMap = keyMapper;
String keyMapping = keyMap.get(String.valueOf(keyCode));
if (TextUtils.isEmpty(keyMapping)) {
return;
}
Runnable runnable = new Runnable() {
@Override
public void run() {
// 待实现按键按下后的逻辑
}
};
runOnUiThread(runnable);
}
// 私有方法:加载网页视图
private void loadWebView() {
if (initedWebEngine) {
return;
}
initedWebEngine = true;
onLoadEngine();
getWindow().setBackgroundDrawableResource(0x7f05002a);
boolean xWalkEnabled = BrowserEngineHelper.isXWalkEnabled();
if (xWalkEnabled) {
XLog.i(TAG, "xwalk enabled, start init.");
Runnable runnable = new Runnable() {
@Override
public void run() {
// 待实现 XWalk 初始化后的逻辑
}
};
BrowserEngineHelper.initXwalk(this, runnable);
} else {
boolean x5Enabled = BrowserEngineHelper.isX5Enabled();
if (x5Enabled) {
XLog.i(TAG, "x5 enabled, start init.");
Runnable runnable = new Runnable() {
@Override
public void run() {
// 待实现 X5 初始化后的逻辑
}
};
BrowserEngineHelper.initX5(getApplicationContext(), runnable);
} else {
Runnable runnable = new Runnable() {
@Override
public void run() {
// 待实现默认情况下的逻辑
}
};
runOnUiThread(runnable);
}
}
}
// 私有方法:显示 XWalk 加载错误对话框
private AlertDialog showXWalkLoadErrorDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(0x7f0e005a);
builder.setMessage(0x7f0e00c6);
builder.setPositiveButton(0x7f0e0099, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 待实现正按钮点击逻辑
}
});
builder.setNegativeButton(0x7f0e005c, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 待实现负按钮点击逻辑
}
});
return builder.show();
}
// 受保护的虚拟方法:获取当前引擎名称
protected String currentEngine() {
IWebView webView = this.webView;
if (webView == null) {
return "";
}
if (webView instanceof AndroidWebView) {
return "webview";
} else {
return "xwalk";
}
}
// 受保护的虚拟方法:关闭设备码显示
protected void dismissDeviceCode() {
// 待实现关闭设备码显示的逻辑
}
// 受保护的虚拟方法:根据内容提供者获取用户名
protected String getUserNameByContentProvider() {
return "";
}
// 受保护的虚拟方法:返回上一页(通过回调实现)
protected void goBack(ValueCallback<Boolean> valueCallback) {
IWebView webView = this.webView;
if (webView == null) {
valueCallback.onReceiveValue(Boolean.valueOf(false));
return;
}
Runnable runnable = new Runnable() {
@Override
public void run() {
dispatchKey2Js(valueCallback, "back");
}
};
dispatchKey2Js(valueCallback, "back");
}
// 受保护的虚拟方法:处理返回键按下
protected void handleBackPressed() {
// 待实现处理返回键按下的逻辑
}
// 受保护的虚拟方法:初始化网页视图
protected IWebView initWebView() {
IWebView webView = this.webView;
if (webView!= null) {
ViewGroup rootView = this.rootView;
rootView.removeView(webView.getWebView());
}
FrameLayout playerContainer = this.playerContainer;
if (playerContainer!= null) {
WebPlayerFactory.disposeAllPlayer();
playerContainer.removeAllViews();
}
FrameLayout webViewContainer = this.webViewContainer;
if (webViewContainer!= null) {
WebViewFactory.disposeAllWebView();
webViewContainer.removeAllViews();
}
try {
IWebView webView1 = BrowserEngineHelper.getCurrentBrowserEngine(getApplicationContext());
this.webView = webView1;
View webViewView = webView1.getWebView();
webViewView.setBackgroundColor(0);
BridgeHandler bridgeHandler = new BridgeHandler() {
@Override
public void handle(String action, Map<String, String> params) {
// 待实现桥接处理逻辑
}
};
webView1.setBridgeHandler(bridgeHandler);
webView1.setWebViewClient(new EvsWebViewClient(this, timeoutTrigger));
rootView.addView(webViewView, -1, -1);
boolean hardwareAccelerated = webViewView.isHardwareAccelerated();
XLog.i(TAG, "isHardwareAccelerated ===> " + hardwareAccelerated);
return webView1;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// 受保护的虚拟方法:加载 URL
protected void loadUrl(String url) {
try {
IWebView webView = this.webView;
webView.loadData(url);
onStartLoadUrl(url);
} catch (Exception e) {
e.printStackTrace();
Runnable timeoutRunnable = timeoutTrigger;
cancelRun(timeoutRunnable);
Runnable runnable = timeoutTrigger;
delayRunOnUiThread(runnable, TIMEOUT_LOADING);
}
}
// 受保护的虚拟方法:活动结果处理
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
IWebView webView = this.webView;
if (webView!= null) {
webView.onActivityResult(requestCode, resultCode, data);
}
}
// 受保护的虚拟方法:浏览器准备就绪时的处理
protected void onBrowserReady() {
// 待实现浏览器准备就绪的逻辑
}
// 受保护的虚拟方法:创建活动时的处理
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
// 受保护的虚拟方法:销毁活动时的处理
protected void onDestroy() {
super.onDestroy();
WebPlayerFactory.disposeAllPlayer();
FrameLayout playerContainer = this.playerContainer;
if (playerContainer!= null) {
playerContainer.removeAllViews();
}
WebViewFactory.disposeAllWebView();
FrameLayout webViewContainer = this.webViewContainer;
if (webViewContainer!= null) {
webViewContainer.removeAllViews();
}
IWebView webView = this.webView;
if (webView!= null) {
webView.onDestroy();
}
}
// 受保护的虚拟方法:加载引擎时的处理
protected void onLoadEngine() {
// 待实现加载引擎的逻辑
}
// 受保护的虚拟方法:页面加载错误时的处理
protected void onLoadPageError(AppWebResourceError error, String url) {
// 待实现页面加载错误的逻辑
}
// 受保护的虚拟方法:页面加载完成时的处理
protected void onLoadPageFinished(String url) {
// 待实现页面加载完成的逻辑
}
// 受保护的虚拟方法:页面加载超时的处理
protected void onLoadPageTimeout() {
// 待实现页面加载超时的逻辑
}
// 受保护的虚拟方法:新意图处理
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
IWebView webView = this.webView;
if (webView!= null) {
webView.onNewIntent(intent);
}
}
// 受保护的虚拟方法:恢复活动时的处理
protected void onResume() {
super.onResume();
IWebView webView = this.webView;
if (webView!= null) {
webView.onResume();
}
}
// 受保护的虚拟方法:重试加载页面时的处理
protected void onRetryLoadPage() {
// 待实现重试加载页面的逻辑
}
// 受保护的虚拟方法:显示图片时的处理
protected void onShowImage(String url, String title, String description) {
// 待实现显示图片的逻辑
}
// 受保护的虚拟方法:显示跑马灯文本时的处理
protected void onShowMarqueeText(String text, String title, String description) {
// 待实现显示跑马灯文本的逻辑
}
// 受保护的虚拟方法:开始加载 URL 时的处理
protected void onStartLoadUrl(String url) {
// 待实现开始加载 URL 的逻辑
}
// 受保护的虚拟方法:停止活动时的处理
protected void onStop() {
super.onStop();
IWebView webView = this.webView;
if (webView!= null) {
webView.onPause();
}
}
// 受保护的虚拟方法:重新加载页面
protected void reloadPage() {
removeAllOutViews();
IWebView webView = this.webView;
if (webView!= null) {
webView.reload();
}
}
// 受保护的虚拟方法:移除所有外部视图
protected void removeAllOutViews() {
try {
WebPlayerFactory.disposeAllPlayer();
FrameLayout playerContainer = this.playerContainer;
playerContainer.removeAllViews();
WebViewFactory.disposeAllWebView();
FrameLayout webViewContainer = this.webViewContainer;
webViewContainer.removeAllViews();
} catch (Exception e) {
e.printStackTrace();
}
}
// 受保护的虚拟方法:设置网页播放器容器
protected void setWebPlayerContainer(FrameLayout frameLayout) {
playerContainer = frameLayout;
}
// 受保护的虚拟方法:设置网页视图容器(根视图组)
protected void setWebViewContainer(ViewGroup viewGroup) {
rootView = viewGroup;
loadWebView();
}
// 受保护的虚拟方法:设置网页视图组
protected void setWebViewGroup(FrameLayout frameLayout) {
webViewContainer = frameLayout;
}
// 受保护的虚拟方法:显示设备码
protected void showDeviceCode(String code) {
// 待实现显示设备码的逻辑
}
// 公共方法:分发按键事件
public boolean dispatchKeyEvent(KeyEvent event) {
FrameLayout playerContainer = this.playerContainer;
if (playerContainer!= null) {
int childCount = playerContainer.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = playerContainer.getChildAt(i);
if (child.isFocusable()) {
boolean result = child.dispatchKeyEvent(event);
if (result) {
backKeyHasDown = true;
return true;
}
}
}
}
FrameLayout webViewContainer = this.webViewContainer;
if (webViewContainer!= null) {
int childCount = webViewContainer.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = webViewContainer.getChildAt(i);
if (child.isFocusable()) {
boolean result = child.dispatchKeyEvent(event);
if (result) {
backKeyHasDown = true;
return true;
}
}
}
}
int action = event.getAction();
if (action == KeyEvent.ACTION_DOWN) {
backKeyHasDown = true;
int keyCode = event.getKeyCode();
if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == 0x42 || keyCode == 0x6f) {
handleKeyDown(keyCode);
} else {
switch (keyCode) {
case 0x13:
handleKeyDown(keyCode);
break;
case 0x14:
handleKeyDown(keyCode);
break;
case 0x15:
handleKeyDown(keyCode);
break;
case 0x16:
handleKeyDown(keyCode);
break;
case 0x17:
handleKeyDown(keyCode);
break;
}
}
} else if (action == KeyEvent.ACTION_UP && backKeyHasDown) {
backKeyHasDown = false;
int keyCode = event.getKeyCode();
}
}
}
安卓WebViewProxy
java
package com.qisyun.sunday.webview;
import android.content.Context;
import android.view.View;
import android.view.ViewParent;
import android.view.ViewGroup.LayoutParams;
import android.webkit.ValueCallback;
public class WebViewProxy implements IWebView {
// 静态字段
private static final String TAG = "WebViewProxy";
// 实例字段
private JSDelegate jsDelegate;
private IWebView webView;
// 构造方法
public WebViewProxy(Context context) {
webView = null;
webView = new AndroidWebView(context, true);
EvsWebViewClient webViewClient = new EvsWebViewClient(this, null);
webView.setWebViewClient(webViewClient);
}
// 静态方法:回调方法
static void access$100(WebViewProxy proxy, String methodName, Object[] args) {
proxy.callback(methodName, args);
}
// 私有方法:可变参数回调方法
private void callback(String methodName, Object[] args) {
if (jsDelegate!= null) {
jsDelegate.call(methodName, args);
}
}
// 实现 IWebView 接口的方法:调用 JavaScript
@Override
public void callJs(String script, ValueCallback<String> callback) {
webView.callJs(script, callback);
}
// 实现 IWebView 接口的方法:检查并返回上一页
@Override
public boolean checkAndGoBack() {
return webView.checkAndGoBack();
}
// 实现 IWebView 接口的方法:获取布局参数
@Override
public LayoutParams getLayoutParams() {
return webView.getLayoutParams();
}
// 实现 IWebView 接口的方法:获取父视图
@Override
public ViewParent getParentView() {
return webView.getParentView();
}
// 实现 IWebView 接口的方法:获取 QsyBridge
@Override
public QsyBridge getQsyBridge() {
return webView.getQsyBridge();
}
// 实现 IWebView 接口的方法:获取网页视图
@Override
public View getWebView() {
return webView.getWebView();
}
// 实现 IWebView 接口的方法:获取网页视图 ID
@Override
public String getWebViewId() {
return webView.getWebViewId();
}
// 实现 IWebView 接口的方法:加载数据
@Override
public void loadData(String data) {
webView.loadData(data);
}
// 实现 IWebView 接口的方法:处理活动结果
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
webView.onActivityResult(requestCode, resultCode, data);
}
// 实现 IWebView 接口的方法:销毁
@Override
public void onDestroy() {
webView.onDestroy();
}
// 实现 IWebView 接口的方法:处理新意图
@Override
public boolean onNewIntent(Intent intent) {
return webView.onNewIntent(intent);
}
// 实现 IWebView 接口的方法:暂停
@Override
public void onPause() {
webView.onPause();
}
// 实现 IWebView 接口的方法:恢复
@Override
public void onResume() {
webView.onResume();
}
// 实现 IWebView 接口的方法:重新加载
@Override
public void reload() {
webView.reload();
}
// 实现 IWebView 接口的方法:移除播放器视图
@Override
public void removePlayerView(IWebPlayer webPlayer) {
webView.removePlayerView(webPlayer);
}
// 实现 IWebView 接口的方法:移除网页视图
@Override
public void removeWebView(IWebView webViewToRemove) {
webView.removeWebView(webViewToRemove);
}
// 实现 IWebView 接口的方法:设置桥接处理器
@Override
public void setBridgeHandler(BridgeHandler bridgeHandler) {
webView.setBridgeHandler(bridgeHandler);
}
// 实现 IWebView 接口的方法:设置 JavaScript 委托
@Override
public void setJsDelegate(JSDelegate jsDelegate) {
this.jsDelegate = jsDelegate;
}
// 实现 IWebView 接口的方法:设置位置和大小
@Override
public void setPositionAndSize(int x, int y, int width, int height) {
webView.setPositionAndSize(x, y, width, height);
}
// 实现 IWebView 接口的方法:设置网页视图客户端
@Override
public void setWebViewClient(WebViewClient webViewClient) {
webView.setWebViewClient(webViewClient);
}
// 实现 IWebView 接口的方法:显示播放器视图
@Override
public void showPlayerView(IWebPlayer webPlayer) {
webView.showPlayerView(webPlayer);
}
// 实现 IWebView 接口的方法:显示网页视图
@Override
public void showWebView(IWebView webViewToShow) {
webView.showWebView(webViewToShow);
}
}
安卓 WebView
java
package com.qisyun.sunday.webview;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.ViewParent;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.qisyun.common.Utils;
import com.qisyun.plugin.core.IManager;
import com.qisyun.plugin.host.ManagerPluginLoader;
import java.lang.reflect.Method;
public class AndroidWebView extends WebView implements IWebView {
// 实例字段
private QsyBridge bridge;
private WebViewClient delegateClient;
private JSDelegate jsDelegate;
private ZlzpPluginJsBridgeImpl pluginJsBridge;
private Rect positionInfo;
private String webviewId;
// 构造方法
public AndroidWebView(Context context) {
this(context, false);
}
// 构造方法
public AndroidWebView(Context context, boolean enableJsBridge) {
this(context, null, enableJsBridge);
}
// 构造方法
public AndroidWebView(Context context, AttributeSet attrs, boolean enableJsBridge) {
super(context, attrs);
initView(context, enableJsBridge);
enableZlzpPluginJsBridge();
}
// 静态方法:获取委托客户端
static WebViewClient access$000(AndroidWebView webView) {
return webView.delegateClient;
}
// 私有方法:构建桥接对象
private QsyBridge buildBridge(BridgeHandler bridgeHandler) {
return new AndroidQsyBridge(bridgeHandler, this);
}
// 私有方法:启用 Zlzp 插件 JavaScript 桥接
private void enableZlzpPluginJsBridge() {
IManager pluginManager = ManagerPluginLoader.getInstance().getPluginManager();
pluginJsBridge = new ZlzpPluginJsBridgeImpl(this, pluginManager);
pluginJsBridge.enableJsBridge();
}
// 私有方法:获取 PC 端用户代理字符串
private String getPCUa() {
boolean isFollowSystemLanguage = LanguageHelper.isFollowSystemLanguage();
if (!isFollowSystemLanguage) {
String currentLanguageKey = LanguageHelper.getCurrentLanguageKey();
if (currentLanguageKey!= null) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" lang/").append(currentLanguageKey);
return stringBuilder.toString();
}
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Mozilla/5.0 (Linux; x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36 zlzp/%s");
Object[] args = new Object[2];
args[0] = getWebviewVersion();
args[1] = AppVersion.getVersionName();
return String.format(stringBuilder.toString(), args);
}
// 私有方法:获取 WebView 版本号
private String getWebviewVersion() {
String systemWebViewVersion = AppVersion.getSystemWebViewVersion();
if (!TextUtils.isEmpty(systemWebViewVersion)) {
return systemWebViewVersion;
} else {
return "53.0.2785.143";
}
}
// 私有方法:初始化视图
private void initView(Context context, boolean enableJsBridge) {
webviewId = Utils.randomId();
setWebViewClient(new AndroidWebView$1(this));
setWebChromeClient(new AndroidWebView$2(this, context));
setHorizontalFadingEdgeEnabled(false);
setVerticalFadingEdgeEnabled(false);
setFadingEdgeLength(0);
setOverScrollMode(2);
setFocusable(true);
setLayerType(0, null);
if (Build.VERSION.SDK_INT >= 21) {
setFocusedByDefault(true);
}
setFocusableInTouchMode(true);
requestFocusFromTouch();
setDrawingCacheEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setWebContentsDebuggingEnabled(true);
}
WebSettings settings = getSettings();
settings.setCacheMode(-1);
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
settings.setAllowFileAccess(true);
settings.setDatabaseEnabled(true);
settings.setLoadsImagesAutomatically(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
settings.setPluginState(WebSettings.PluginState.ON);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
settings.setMediaPlaybackRequiresUserGesture(false);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
settings.setAllowFileAccessFromFileURLs(true);
settings.setAllowUniversalAccessFromFileURLs(true);
}
settings.setLoadWithOverviewMode(true);
settings.setUseWideViewPort(false);
String userAgent = getPCUa();
settings.setUserAgentString(userAgent);
setInitialScale(100);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().setAcceptThirdPartyCookies(this, true);
}
}
// 实现 IWebView 接口的方法:调用 JavaScript
@Override
public void callJs(String script, ValueCallback<String> callback) {
AndroidWebView$3 runnable = new AndroidWebView$3(this, script, callback);
Looper myLooper = Looper.myLooper();
Looper mainLooper = Looper.getMainLooper();
if (myLooper == mainLooper) {
runnable.run();
} else {
post(runnable);
}
}
// 实现 IWebView 接口的方法:检查并返回上一页
@Override
public boolean checkAndGoBack() {
if (canGoBack()) {
goBack();
return true;
} else {
return false;
}
}
// 重写 dispatchKeyEvent 方法
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (canGoBack() && event.getAction() == KeyEvent.ACTION_DOWN) {
goBack();
return true;
}
}
return super.dispatchKeyEvent(event);
}
// 实现 IWebView 接口的方法:获取布局参数
@Override
public LayoutParams getLayoutParams() {
Rect positionInfo = this.positionInfo;
if (positionInfo!= null) {
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(positionInfo.width(), positionInfo.height());
layoutParams.leftMargin = positionInfo.left;
layoutParams.topMargin = positionInfo.top;
return layoutParams;
} else {
return super.getLayoutParams();
}
}
// 实现 IWebView 接口的方法:获取父视图
@Override
public ViewParent getParentView() {
return getParent();
}
// 实现 IWebView 接口的方法:获取 QsyBridge
@Override
public QsyBridge getQsyBridge() {
return bridge;
}
// 实现 IWebView 接口的方法:获取网页视图
@Override
public View getWebView() {
return this;
}
// 实现 IWebView 接口的方法:获取网页视图 ID
@Override
public String getWebViewId() {
return webviewId;
}
// 实现 IWebView 接口的方法:加载数据
@Override
public void loadData(String data) {
loadUrl(data);
}
// 实现 IWebView 接口的方法:原生播放器支持
@Override
public boolean nativePlayer() {
return true;
}
// 实现 IWebView 接口的方法:处理活动结果
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// 空实现
}
// 重写 onAttachedToWindow 方法
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
requestFocus();
requestFocusFromTouch();
}
// 实现 IWebView 接口的方法:销毁
@Override
public void onDestroy() {
super.onDetachedFromWindow();
}
// 实现 IWebView 接口的方法:处理新意图
@Override
public boolean onNewIntent(Intent intent) {
return false;
}
// 实现 IWebView 接口的方法:暂停
@Override
public void onPause() {
super.onPause();
pauseTimers();
}
// 实现 IWebView 接口的方法:恢复
@Override
public void onResume() {
super.onResume();
resumeTimers();
}
// 实现 IWebView 接口的方法:重新加载
@Override
public void reload() {
super.reload();
}
// 实现 IWebView 接口的方法:移除播放器视图
@Override
public void removePlayerView(IWebPlayer webPlayer) {
WebViewClient delegateClient = this.delegateClient;
if (delegateClient!= null) {
delegateClient.removePlayerView(webPlayer);
}
}
// 实现 IWebView 接口的方法:移除网页视图
@Override
public void removeWebView(IWebView webViewToRemove) {
WebViewClient delegateClient = this.delegateClient;
if (delegateClient!= null) {
delegateClient.removeWebView(webViewToRemove);
}
}
// 实现 IWebView 接口的方法:设置桥接处理器
@Override
public void setBridgeHandler(BridgeHandler bridgeHandler) {
bridge = buildBridge(bridgeHandler);
String bridgeName = bridge.getName();
addJavascriptInterface(bridge, bridgeName);
}
// 实现 IWebView 接口的方法:设置 JavaScript 委托
@Override
public void setJsDelegate(JSDelegate jsDelegate) {
this.jsDelegate = jsDelegate;
}
// 实现 IWebView 接口的方法:设置位置和大小
@Override
public void setPositionAndSize(int x, int y, int width, int height) {
Rect positionInfo = this.positionInfo;
if (positionInfo == null) {
positionInfo = new Rect();
this.positionInfo = positionInfo;
}
positionInfo.set(x, y, x + width, y + height);
}
// 实现 IWebView 接口的方法:设置网页视图客户端
@Override
public void setWebViewClient(WebViewClient webViewClient) {
this.delegateClient = webViewClient;
}
// 实现 IWebView 接口的方法:显示播放器视图
@Override
public void showPlayerView(IWebPlayer webPlayer) {
WebViewClient delegateClient = this.delegateClient;
if (delegateClient!= null) {
delegateClient.showPlayerView(webPlayer);
}
}
// 实现 IWebView 接口的方法:显示网页视图
@Override
public void showWebView(IWebView webViewToShow) {
WebViewClient delegateClient = this.delegateClient;
if (delegateClient!= null) {
delegateClient.showWebView(webViewToShow);
}
}
}
实现三方游览器
java
package com.qisyun.sunday.webview;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.ViewParent;
import android.webkit.ValueCallback;
import org.json.JSONException;
import org.json.JSONObject;
import org.xwalk.core.XWalkNavigationHistory;
import org.xwalk.core.XWalkNavigationHistory.Direction;
import org.xwalk.core.XWalkPreferences;
import org.xwalk.core.XWalkResourceClient;
import org.xwalk.core.XWalkUIClient;
import org.xwalk.core.XWalkView;
import org.xwalk.core.XWalkWebViewBridge;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringBuilder;
public class XWalkWebView extends XWalkView implements IWebView {
// 静态字段
public static final String MANIFEST_ASSETS_PATH = "xwalk/manifest.json";
public static final String TAG = "XWalkWebView";
// 实例字段
private QsyBridge bridge;
private XWalkCookieManager cookieManager;
private JSDelegate jsDelegate;
private ZlzpPluginJsBridgeImpl pluginJsBridge;
private Rect positionInfo;
private WebViewClient webViewClient;
private String webViewId;
// 构造方法
public XWalkWebView(Context context) {
this(context, null);
}
// 构造方法
public XWalkWebView(Context context, AttributeSet attrs) {
super(context, attrs);
positionInfo = null;
initXWalk(context);
enableZlzpPluginJsBridge();
}
// 静态方法:获取 WebViewClient
static WebViewClient access$000(XWalkWebView webView) {
return webView.webViewClient;
}
// 静态方法:获取 XWalkCookieManager
static XWalkCookieManager access$100(XWalkWebView webView) {
return webView.cookieManager;
}
// 私有方法:构建桥接对象
private QsyBridge buildBridge(BridgeHandler bridgeHandler) {
return new XwalkQsyBridge(bridgeHandler, this);
}
// 静态方法:关闭可关闭资源
public static void close(Closeable closeable) {
if (closeable!= null) {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 私有方法:启用 Zlzp 插件 JavaScript 桥接
private void enableZlzpPluginJsBridge() {
IManager pluginManager = ManagerPluginLoader.getInstance().getPluginManager();
pluginJsBridge = new ZlzpPluginJsBridgeImpl(this, pluginManager);
pluginJsBridge.enableJsBridge();
}
// 私有方法:获取 PC 端用户代理字符串
private String getPCUa() {
boolean isFollowSystemLanguage = LanguageHelper.isFollowSystemLanguage();
if (!isFollowSystemLanguage) {
String currentLanguageKey = LanguageHelper.getCurrentLanguageKey();
if (currentLanguageKey!= null) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" lang/").append(currentLanguageKey);
return stringBuilder.toString();
}
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Mozilla/5.0 (Linux; x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Xwalk/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36 zlzp/%s");
Object[] args = new Object[1];
args[0] = AppVersion.getVersionName();
return String.format(stringBuilder.toString(), args);
}
// 私有方法:初始化 XWalk
private void initXWalk(Context context) {
webViewId = Utils.randomId();
XWalkPreferences.setValue("remote-debugging", true);
XWalkPreferences.setValue("allow-universal-access-from-file", true);
EvsXWalkResourceClient resourceClient = new EvsXWalkResourceClient(this, this);
setResourceClient(resourceClient);
EvsUiClient uiClient = new EvsUiClient(this, this);
setUIClient(uiClient);
setHorizontalFadingEdgeEnabled(false);
setVerticalFadingEdgeEnabled(false);
setFadingEdgeLength(0);
setOverScrollMode(2);
setKeepScreenOn(true);
setZOrderOnTop(false);
XWalkSettings settings = getSettings();
settings.setLoadsImagesAutomatically(true);
settings.setMediaPlaybackRequiresUserGesture(false);
settings.setJavaScriptEnabled(true);
settings.setAllowFileAccess(true);
settings.setAllowUniversalAccessFromFileURLs(true);
settings.setSupportZoom(false);
settings.setBuiltInZoomControls(false);
settings.setCacheMode(-1);
settings.setDomStorageEnabled(true);
settings.setDatabaseEnabled(true);
settings.setInitialPageScale(100.0f);
settings.setUseWideViewPort(false);
String userAgent = getPCUa();
settings.setUserAgentString(userAgent);
XWalkCookieManager cookieManager = new XWalkCookieManager();
this.cookieManager = cookieManager;
}
// 静态方法:将输入流转换为字符串
public static String stream2String(InputStream inputStream) throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine())!= null) {
stringBuilder.append(line);
}
close(bufferedReader);
close(inputStreamReader);
close(inputStream);
return stringBuilder.toString();
}
// 实现 IWebView 接口的方法:调用 JavaScript
@Override
public void callJs(String script, ValueCallback<String> callback) {
Looper myLooper = Looper.myLooper();
Looper mainLooper = Looper.getMainLooper();
if (myLooper == mainLooper) {
Object[] args = new Object[1];
args[0] = script;
String formattedScript = String.format("%s", args);
evaluateJavascript(formattedScript, callback);
} else {
XWalkWebView$1 runnable = new XWalkWebView$1(this, script, callback);
post(runnable);
}
}
// 实现 IWebView 接口的方法:检查并返回上一页
@Override
public boolean checkAndGoBack() {
XWalkNavigationHistory navigationHistory = getNavigationHistory();
if (navigationHistory.canGoBack()) {
navigationHistory.navigate(Direction.BACKWARD, 1);
return true;
} else {
return false;
}
}
// 实现 IWebView 接口的方法:获取布局参数
@Override
public LayoutParams getLayoutParams() {
Rect positionInfo = this.positionInfo;
if (positionInfo!= null) {
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(positionInfo.width(), positionInfo.height());
layoutParams.leftMargin = positionInfo.left;
layoutParams.topMargin = positionInfo.top;
return layoutParams;
} else {
return super.getLayoutParams();
}
}
// 实现 IWebView 接口的方法:获取父视图
@Override
public ViewParent getParentView() {
return getParent();
}
// 实现 IWebView 接口的方法:获取 QsyBridge
@Override
public QsyBridge getQsyBridge() {
return bridge;
}
// 实现 IWebView 接口的方法:获取网页视图
@Override
public View getWebView() {
return this;
}
// 实现 IWebView 接口的方法:获取网页视图 ID
@Override
public String getWebViewId() {
return webViewId;
}
// 实现 IWebView 接口的方法:加载数据
@Override
public void loadData(String data) {
try {
InputStream inputStream = getContext().getAssets().open(MANIFEST_ASSETS_PATH);
String manifestString = stream2String(inputStream);
JSONObject jsonObject = new JSONObject(manifestString);
jsonObject.put("start_url", data);
String updatedManifest = jsonObject.toString();
loadAppFromManifest("", updatedManifest);
} catch (IOException | JSONException e) {
if (e instanceof JSONException) {
e.printStackTrace();
} else {
XLog.e(TAG, "build xwalk config error!!!");
}
}
}
// 实现 IWebView 接口的方法:原生播放器支持
@Override
public boolean nativePlayer() {
return true;
}
// 实现 IWebView 接口的方法:销毁
@Override
public void onDestroy() {
super.onDestroy();
}
// 实现 IWebView 接口的方法:处理新意图
@Override
public boolean onNewIntent(Intent intent) {
return super.onNewIntent(intent);
}
// 实现 IWebView 接口的方法:暂停
@Override
public void onPause() {
pauseTimers();
onHide();
}
// 实现 IWebView 接口的方法:恢复
@Override
public void onResume() {
resumeTimers();
onShow();
}
// 实现 IWebView 接口的方法:重新加载
@Override
public void reload() {
super.reload(1);
}
// 实现 IWebView 接口的方法:移除播放器视图
@Override
public void removePlayerView(IWebPlayer webPlayer) {
WebViewClient webViewClient = this.webViewClient;
if (webViewClient!= null) {
webViewClient.removePlayerView(webPlayer);
}
}
// 实现 IWebView 接口的方法:移除网页视图
@Override
public void removeWebView(IWebView webViewToRemove) {
WebViewClient webViewClient = this.webViewClient;
if (webViewClient!= null) {
webViewClient.removeWebView(webViewToRemove);
}
}
// 实现 IWebView 接口的方法:设置桥接处理器
@Override
public void setBridgeHandler(BridgeHandler bridgeHandler) {
bridge = buildBridge(bridgeHandler);
String bridgeName = bridge.getName();
addJavascriptInterface(bridge, bridgeName);
}
// 实现 IWebView 接口的方法:设置 JavaScript 委托
@Override
public void setJsDelegate(JSDelegate jsDelegate) {
this.jsDelegate = jsDelegate;
}
// 实现 IWebView 接口的方法:设置位置和大小
@Override
public void setPositionAndSize(int x, int y, int width, int height) {
Rect positionInfo = this.positionInfo;
if (positionInfo == null) {
positionInfo = new Rect();
this.positionInfo = positionInfo;
}
positionInfo.set(x, y, x + width, y + height);
}
// 实现 IWebView 接口的方法:设置网页视图客户端
@Override
public void setWebViewClient(WebViewClient webViewClient) {
this.webViewClient = webViewClient;
}
// 实现 IWebView 接口的方法:显示播放器视图
@Override
public void showPlayerView(IWebPlayer webPlayer) {
WebViewClient webViewClient = this.webViewClient;
if (webViewClient!= null) {
webViewClient.showPlayerView(webPlayer);
}
}
// 实现 IWebView 接口的方法:显示网页视图
@Override
public void showWebView(IWebView webViewToShow) {
WebViewClient webViewClient = this.webViewClient;
if (webViewClient!= null) {
webViewClient.showWebView(webViewToShow);
}
}
}
安卓WebPlayer工厂
java
package com.qisyun.sunday.webview;
import android.content.Context;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class WebPlayerFactory {
// 静态字段
private static final Map<String, IWebPlayer> repos;
// 静态初始化块
static {
repos = new HashMap<>();
}
// 私有构造方法
private WebPlayerFactory() {
super();
}
// 创建 Web 播放器实例并将其存储在映射中
public static IWebPlayer create(Context context, WebPlayerFactory.Creator creator) {
IWebPlayer webPlayer = creator.create(context);
repos.put(webPlayer.getPlayerId(), webPlayer);
return webPlayer;
}
// 释放所有播放器
public static void disposeAllPlayer() {
Set<Map.Entry<String, IWebPlayer>> entrySet = repos.entrySet();
Iterator<Map.Entry<String, IWebPlayer>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
Map.Entry<String, IWebPlayer> entry = iterator.next();
IWebPlayer webPlayer = entry.getValue();
if (webPlayer!= null) {
webPlayer.stop();
}
}
repos.clear();
}
// 根据播放器 ID 释放特定播放器
public static void disposePlayer(String playerId) {
repos.remove(playerId);
}
// 根据播放器 ID 获取播放器实例
public static IWebPlayer getPlayer(String playerId) {
return repos.get(playerId);
}
// 内部接口用于创建 Web 播放器
public interface Creator {
IWebPlayer create(Context context);
}
}
安卓原生播放器
java
package com.qisyun.sunday.activities.component.welcome;
import android.content.Context;
import android.graphics.Point;
import android.media.MediaPlayer;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.View.MeasureSpec;
import java.util.Map;
public class VideoView extends TextureView {
// 静态字段
private static final int STATE_ERROR = -1;
private static final int STATE_IDLE = 0;
private static final int STATE_PAUSED = 4;
private static final int STATE_PLAYBACK_COMPLETED = 5;
private static final int STATE_PLAYING = 3;
private static final int STATE_PREPARED = 2;
private static final int STATE_PREPARING = 1;
private static final String TAG = "VideoView";
// 实例字段
private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener;
private MediaPlayer.OnCompletionListener mCompletionListener;
private int mCurrentBufferPercentage;
private int mCurrentState;
private MediaPlayer.OnErrorListener mErrorListener;
private Map<String, String> mHeaders;
private MediaPlayer.OnInfoListener mInfoListener;
private MediaPlayer mMediaPlayer;
private MediaPlayer.OnCompletionListener mOnCompletionListener;
private MediaPlayer.OnErrorListener mOnErrorListener;
private MediaPlayer.OnInfoListener mOnInfoListener;
private MediaPlayer.OnPreparedListener mOnPreparedListener;
private MediaPlayer.OnPreparedListener mPreparedListener;
private int mSeekWhenPrepared;
private MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener;
private Surface mSurface;
private int mSurfaceHeight;
private int mSurfaceWidth;
private int mTargetState;
private Uri mUri;
private int mVideoHeight;
private int mVideoWidth;
private TextureView.SurfaceTextureListener textureListener;
// 构造方法
public VideoView(Context context) {
this(context, null);
}
public VideoView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public VideoView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// 设置视频大小变化监听器
mSizeChangedListener = new VideoView$1(this);
setOnVideoSizeChangedListener(mSizeChangedListener);
// 设置视频准备好监听器
mPreparedListener = new VideoView$2(this);
setOnPreparedListener(mPreparedListener);
// 设置视频播放完成监听器
mCompletionListener = new VideoView$3(this);
setOnCompletionListener(mCompletionListener);
// 设置视频信息监听器
mInfoListener = new VideoView$4(this);
setOnInfoListener(mInfoListener);
// 设置视频错误监听器
mErrorListener = new VideoView$5(this);
setOnErrorListener(mErrorListener);
// 设置视频缓冲更新监听器
mBufferingUpdateListener = new VideoView$6(this);
setOnBufferingUpdateListener(mBufferingUpdateListener);
// 设置纹理监听器
textureListener = new VideoView$7(this);
setSurfaceTextureListener(textureListener);
mVideoWidth = 0;
mVideoHeight = 0;
setFocusable(true);
setFocusableInTouchMode(true);
requestFocus();
mCurrentState = STATE_IDLE;
mTargetState = STATE_IDLE;
}
// 静态方法访问器
static int access$000(VideoView videoView) {
return videoView.mVideoWidth;
}
static int access$002(VideoView videoView, int value) {
return videoView.mVideoWidth = value;
}
static int access$100(VideoView videoView) {
return videoView.mVideoHeight;
}
static int access$1002(VideoView videoView, int value) {
return videoView.mCurrentBufferPercentage = value;
}
static int access$102(VideoView videoView, int value) {
return videoView.mVideoHeight = value;
}
static Surface access$1102(VideoView videoView, Surface surface) {
return videoView.mSurface = surface;
}
static int access$1202(VideoView videoView, int value) {
return videoView.mSurfaceWidth = value;
}
static int access$1302(VideoView videoView, int value) {
return videoView.mSurfaceHeight = value;
}
static void access$1400(VideoView videoView) {
videoView.openVideo();
}
static void access$1500(VideoView videoView, boolean releaseImmediately) {
videoView.release(releaseImmediately);
}
static int access$202(VideoView videoView, int value) {
return videoView.mCurrentState = value;
}
static MediaPlayer.OnPreparedListener access$300(VideoView videoView) {
return videoView.mOnPreparedListener;
}
static MediaPlayer access$400(VideoView videoView) {
return videoView.mMediaPlayer;
}
static int access$500(VideoView videoView) {
return videoView.mSeekWhenPrepared;
}
static int access$600(VideoView videoView) {
return videoView.mTargetState;
}
static int access$602(VideoView videoView, int value) {
return videoView.mTargetState = value;
}
static MediaPlayer.OnCompletionListener access$700(VideoView videoView) {
return videoView.mOnCompletionListener;
}
static MediaPlayer.OnInfoListener access$800(VideoView videoView) {
return videoView.mOnInfoListener;
}
static MediaPlayer.OnErrorListener access$900(VideoView videoView) {
return videoView.mOnErrorListener;
}
// 判断是否处于播放状态
private boolean isInPlaybackState() {
MediaPlayer mediaPlayer = mMediaPlayer;
if (mediaPlayer == null) {
return false;
}
int currentState = mCurrentState;
return currentState!= STATE_ERROR && currentState!= STATE_IDLE && currentState!= 1;
}
// 打开视频
private void openVideo() {
Uri uri = mUri;
if (uri!= null && mSurface!= null) {
release(false);
MediaPlayer mediaPlayer = new MediaPlayer();
setMediaPlayerListeners(mediaPlayer);
try {
mediaPlayer.setDataSource(getContext(), uri, mHeaders);
mediaPlayer.setSurface(mSurface);
mediaPlayer.setScreenOnWhilePlaying(true);
mediaPlayer.prepareAsync();
mCurrentState = STATE_PREPARING;
} catch (IOException | IllegalArgumentException e) {
Log.w(TAG, "Unable to open content: " + uri, e);
mCurrentState = STATE_ERROR;
mTargetState = STATE_ERROR;
if (mErrorListener!= null && mediaPlayer!= null) {
mErrorListener.onError(mediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
}
}
}
}
// 设置媒体播放器监听器
private void setMediaPlayerListeners(MediaPlayer mediaPlayer) {
mediaPlayer.setOnPreparedListener(mPreparedListener);
mediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
mediaPlayer.setOnCompletionListener(mCompletionListener);
mediaPlayer.setOnErrorListener(mErrorListener);
mediaPlayer.setOnInfoListener(mInfoListener);
mediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
}
// 释放视频资源
private void release(boolean releaseImmediately) {
MediaPlayer mediaPlayer = mMediaPlayer;
if (mediaPlayer!= null) {
mediaPlayer.reset();
mediaPlayer.release();
mMediaPlayer = null;
mCurrentState = STATE_IDLE;
if (releaseImmediately) {
mTargetState = STATE_IDLE;
}
}
}
// 获取缓冲百分比
public int getBufferPercentage() {
MediaPlayer mediaPlayer = mMediaPlayer;
if (mediaPlayer!= null) {
return mCurrentBufferPercentage;
} else {
return 0;
}
}
// 获取当前播放位置
public int getCurrentPosition() {
if (isInPlaybackState()) {
MediaPlayer mediaPlayer = mMediaPlayer;
if (mediaPlayer!= null) {
return mediaPlayer.getCurrentPosition();
}
}
return 0;
}
// 获取视频总时长
public int getDuration() {
if (isInPlaybackState()) {
MediaPlayer mediaPlayer = mMediaPlayer;
if (mediaPlayer!= null) {
return mediaPlayer.getDuration();
}
}
return -1;
}
// 判断视频是否正在播放
public boolean isPlaying() {
if (isInPlaybackState()) {
MediaPlayer mediaPlayer = mMediaPlayer;
if (mediaPlayer!= null && mediaPlayer.isPlaying()) {
return true;
}
}
return false;
}
// 测量视图大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int videoWidth = mVideoWidth;
int videoHeight = mVideoHeight;
if (videoWidth > 0 && videoHeight > 0) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY) {
// 特殊处理
//...
} else {
// 不同情况下的处理
//...
}
setMeasuredDimension(widthSize, heightSize);
}
}
// 暂停播放
public void pause() {
if (isInPlaybackState()) {
MediaPlayer mediaPlayer = mMediaPlayer;
if (mediaPlayer!= null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
mCurrentState = STATE_PAUSED;
mTargetState = STATE_PAUSED;
}
} else {
mTargetState = STATE_PAUSED;
}
}
// 恢复播放
public void resume() {
openVideo();
}
// 跳转到指定位置
public void seekTo(int position) {
if (isInPlaybackState()) {
MediaPlayer mediaPlayer = mMediaPlayer;
if (mediaPlayer!= null) {
mediaPlayer.seekTo(position);
mSeekWhenPrepared = 0;
}
} else {
mSeekWhenPrepared = position;
}
}
// 设置播放完成监听器
public void setOnCompletionListener(MediaPlayer.OnCompletionListener listener) {
mOnCompletionListener = listener;
}
// 设置错误监听器
public void setOnErrorListener(MediaPlayer.OnErrorListener listener) {
mOnErrorListener = listener;
}
// 设置信息监听器
public void setOnInfoListener(MediaPlayer.OnInfoListener listener) {
mOnInfoListener = listener;
}
// 设置准备好监听器
public void setOnPreparedListener(MediaPlayer.OnPreparedListener listener) {
mOnPreparedListener = listener;
}
// 设置视频路径
public void setVideoPath(String path) {
setVideoURI(Uri.parse(path));
}
// 设置视频 URI
public void setVideoURI(Uri uri) {
setVideoURI(uri, null);
}
// 设置视频 URI 和头部信息
public void setVideoURI(Uri uri, Map<String, String> headers) {
mUri = uri;
mHeaders = headers;
mSeekWhenPrepared = 0;
openVideo();
requestLayout();
invalidate();
}
// 开始播放
public void start() {
if (isInPlaybackState()) {
MediaPlayer mediaPlayer = mMediaPlayer;
if (mediaPlayer!= null) {
mediaPlayer.start();
mCurrentState = STATE_PLAYING;
mTargetState = STATE_PLAYING;
}
} else {
mTargetState = STATE_PLAYING;
}
}
// 停止播放
public void stopPlayback() {
MediaPlayer mediaPlayer = mMediaPlayer;
if (mediaPlayer!= null) {
mediaPlayer.stop();
mediaPlayer.release();
mMediaPlayer = null;
mCurrentState = STATE_IDLE;
mTargetState = STATE_IDLE;
}
}
// 暂停播放并释放资源
public void suspend() {
release(false);
}
}