From ad02c90af30493308145999cff687a2e4966c394 Mon Sep 17 00:00:00 2001 From: louzixuan Date: Thu, 18 Jul 2024 20:00:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=A7=E5=B1=8F=E9=80=82=E9=85=8D=E8=A1=A5?= =?UTF-8?q?=E5=85=85=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: louzixuan --- .../java/org/hapjs/model/DisplayInfo.java | 11 +- .../main/java/org/hapjs/render/RootView.java | 111 +++++++++++++++++- .../org/hapjs/render/jsruntime/JsThread.java | 34 ++++++ 3 files changed, 149 insertions(+), 7 deletions(-) diff --git a/core/runtime/android/runtime/src/main/java/org/hapjs/model/DisplayInfo.java b/core/runtime/android/runtime/src/main/java/org/hapjs/model/DisplayInfo.java index 6bbbbbfd..266f74c0 100644 --- a/core/runtime/android/runtime/src/main/java/org/hapjs/model/DisplayInfo.java +++ b/core/runtime/android/runtime/src/main/java/org/hapjs/model/DisplayInfo.java @@ -48,6 +48,7 @@ public class DisplayInfo { private int mThemeMode; // dark-no--0,dark_yes--1,auto-- -1 private JSONObject mPageAnimation; private String mFitMode; + private String mMultiWindowMode; public static final String KEY_NOT_VALID = "FALSE"; public static final String KEY_VALID = "TRUE"; @@ -68,7 +69,7 @@ public static DisplayInfo parse(JSONObject jsonObject) { multiWindowMode = multiWindowConfigJsonObject.optString(KEY_MULTI_WINDOW_CONFIG_MODE); } } - MultiWindowManager.setMultiWindowModeType(multiWindowMode); + displayInfo.setMultiWindowMode(multiWindowMode); } } @@ -99,6 +100,14 @@ public void setFitMode(String fitMode) { mFitMode = fitMode; } + public String getMultiWindowMode() { + return mMultiWindowMode; + } + + public void setMultiWindowMode(String multiWindowMode) { + mMultiWindowMode = multiWindowMode; + } + public Style getDefaultStyle() { return mDefaultStyle; } diff --git a/core/runtime/android/runtime/src/main/java/org/hapjs/render/RootView.java b/core/runtime/android/runtime/src/main/java/org/hapjs/render/RootView.java index 86ebd5ee..0417c3fc 100755 --- a/core/runtime/android/runtime/src/main/java/org/hapjs/render/RootView.java +++ b/core/runtime/android/runtime/src/main/java/org/hapjs/render/RootView.java @@ -50,6 +50,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.greenrobot.eventbus.EventBus; import org.hapjs.bridge.ApplicationContext; +import org.hapjs.bridge.FitWidescreenProvider; import org.hapjs.bridge.HybridRequest; import org.hapjs.bridge.HybridView; import org.hapjs.bridge.impl.android.AndroidViewClient; @@ -874,6 +875,7 @@ protected LoadResult doInBackground() { .getApplicationContext(); mAppInfo = appContext.getAppInfo(false); GrayModeManager.getInstance().init(appContext.getContext().getApplicationContext()); + setFoldScreenFitMode(mAppInfo); if (mAppInfo == null) { return LoadResult.APP_INFO_NULL; } else if (mAppInfo.getMinPlatformVersion() @@ -911,10 +913,6 @@ public void run() { } }); } - if (displayInfo != null) { - String fitMode = displayInfo.getFitMode(); - FoldingUtils.setRpkWideScreenFitMode(fitMode); - } EventManager.getInstance() .invoke(new ApplicationLaunchEvent(mAppInfo.getPackage())); @@ -1044,6 +1042,37 @@ protected void onPostExecute(LoadResult result) { }); } + private void setFoldScreenFitMode(AppInfo appInfo) { + if (appInfo != null) { + DisplayInfo displayInfo = appInfo.getDisplayInfo(); + if (displayInfo != null) { + String fitMode = displayInfo.getFitMode(); + FoldingUtils.setRpkWideScreenFitMode(fitMode); + FitWidescreenProvider provider = ProviderManager.getDefault().getProvider(FitWidescreenProvider.NAME); + String defaultRpkFitMode = provider.getFitMode(null, null); + if (DisplayInfo.MODE_ADAPTIVE_SCREEN.equals(fitMode)) { + FoldingUtils.setRpkWideScreenFitMode(DisplayInfo.MODE_ADAPTIVE_SCREEN); + } else if (DisplayInfo.MODE_MULTI_WINDOW.equals(fitMode)) { + FoldingUtils.setRpkWideScreenFitMode(DisplayInfo.MODE_MULTI_WINDOW); + applyMultiWindowFromManifest(displayInfo); + } else { + FoldingUtils.setRpkWideScreenFitMode(defaultRpkFitMode); + } + } + } + } + + private void applyMultiWindowFromManifest(DisplayInfo displayInfo) { + String multiWindowMode = displayInfo.getMultiWindowMode(); + if (TextUtils.equals(multiWindowMode, DisplayInfo.MODE_SHOPPING)) { + MultiWindowManager.setMultiWindowModeType(MultiWindowManager.SHOPPING_MODE); + } else if (TextUtils.equals(multiWindowMode, DisplayInfo.MODE_NAVIGATION)) { + MultiWindowManager.setMultiWindowModeType(MultiWindowManager.NAVIGATION_MODE); + } else { + MultiWindowManager.setMultiWindowModeType(MultiWindowManager.SHOPPING_MODE); + } + } + private void initConfiguration(ApplicationContext appContext, HybridRequest request) { ConfigurationManager.getInstance().init(appContext); Locale initialLocale = ConfigurationManager.getInstance().getCurrentLocale(); @@ -1124,6 +1153,8 @@ private void handleReloadConfigurationChange(Page reloadPage, Page currentPage, newConfig.setLastScreenSize(newScreenSize); } + mJsThread.addConfigurationNotifyInfo(task); + // update media query when 'theme mode' or 'orientation' has changed. if (configurationChanged) { mJsThread.getRenderActionManager().updateMediaPropertyInfo(currentPage); @@ -1185,6 +1216,7 @@ private void handleConfigurationChange(Page currentPage, VDocument vdoc, HapConf if (isFoldStatus(getContext())) { ReloadPageConfigurationChangedInfo task = new ReloadPageConfigurationChangedInfo(currentPage); task.setOrientationChanged(true); + mJsThread.addConfigurationNotifyInfo(task); } else { mJsThread.postNotifyConfigurationChanged(currentPage, JsThread.CONFIGURATION_TYPE_ORIENTATION); } @@ -1212,8 +1244,8 @@ private void handleConfigurationChange(Page currentPage, VDocument vdoc, HapConf Executors.ui() .execute( () -> { - if (mDocument != null) { - mDocument + if (vdoc != null) { + vdoc .getComponent() .updateTitleBar(Collections.emptyMap(), currentPage.pageId); @@ -1257,6 +1289,66 @@ private void handleConfigurationChangeOnMultiWindow(HapConfiguration config) { mIsFoldingStatus = isFold; } + private Page handleFoldingPagesLoading(HapConfiguration newConfig) { + if (newConfig == null) { + return null; + } + Page page = null; + if (isFoldableDevice(getContext())) { + if (mIsFoldingStatus != isFoldStatus(getContext())) { + // 折叠屏折叠展开状态发生变化后Page处理逻辑 + page = foldDeviceReloadPages(); + } else if (newConfig.getOrientation() != newConfig.getLastOrientation()) { + //adaptiveScreen模式下横竖屏切换时重建Page + if (!isFoldStatus(getContext()) && FoldingUtils.isAdaptiveScreenMode()) { + try { + page = mPageManager.reloadOnFoldableDevice(); + } catch (PageNotFoundException e) { + Log.e(TAG, "onConfigurationChanged reload error", e); + } + } + } + mIsFoldingStatus = isFoldStatus(getContext()); + } + return page; + } + + private Page foldDeviceReloadPages() { + String rpkFitMode = FoldingUtils.getRpkWideScreenFitMode(); + Page newPage = null; + // rpk manifest fitWidthScreenFitMode为居中显示时(或者未配置,默认值为fitScreen) + // fitScreen模式下可以手动切换当前适配模式 + if (DisplayInfo.MODE_FIT_SCREEN.equals(rpkFitMode)) { + // 屏幕折叠展开状态发生变化后页面重新加载 + try { + newPage = mPageManager.reloadOnFoldableDevice(); + } catch (PageNotFoundException e) { + Log.e(TAG, "onConfigurationChanged reload error", e); + } + } else { + // 非fitScreen下,无法修改当前折叠屏适配模式 + if (DisplayInfo.MODE_FILL_SCREEN.equals(rpkFitMode) || DisplayInfo.MODE_ADAPTIVE_SCREEN.equals(rpkFitMode)) { + try { + newPage = mPageManager.reloadOnFoldableDevice(); + } catch (PageNotFoundException e) { + Log.e(TAG, "onConfigurationChanged reload error", e); + } + } else if (DisplayInfo.MODE_ORIGINAL.equals(rpkFitMode)) { + // original模式下所有历史页面刷新样式 + for (Page page : mPageManager.getPageInfos()) { + if (page != getCurrentPage()) { + mJsThread.getRenderActionManager().updateMediaPropertyInfo(page); + } + } + } else { + Log.e(TAG, + "onConfigurationChanged reload error: unknown fold wide screen fit mode status rpkFitMode: " + + rpkFitMode); + } + } + return newPage; + } + private void ReloadPagesOnFoldDeviceOnMultiWindowMode(boolean isFold, Page leftPage, Page rightPage, HapConfiguration config) { Page reloadRightPage = null; Page reloadLeftPage = null; @@ -2310,6 +2402,13 @@ public void onConfigurationChanged(HapConfiguration newConfig) { if (sysOpProvider.isFoldableDevice(rootView.getContext())) { if (FoldingUtils.isMultiWindowMode()) { rootView.handleConfigurationChangeOnMultiWindow(newConfig); + } else { + Page reloadPage = rootView.handleFoldingPagesLoading(newConfig); + if (reloadPage != null) { + rootView.handleReloadConfigurationChange(reloadPage, currentPage, rootView.mDocument, newConfig); + } else { + rootView.handleConfigurationChange(currentPage, rootView.mDocument, newConfig); + } } } else { rootView.handleConfigurationChange(currentPage, rootView.mDocument, newConfig); diff --git a/core/runtime/android/runtime/src/main/java/org/hapjs/render/jsruntime/JsThread.java b/core/runtime/android/runtime/src/main/java/org/hapjs/render/jsruntime/JsThread.java index c9772a47..cae3b719 100755 --- a/core/runtime/android/runtime/src/main/java/org/hapjs/render/jsruntime/JsThread.java +++ b/core/runtime/android/runtime/src/main/java/org/hapjs/render/jsruntime/JsThread.java @@ -153,6 +153,8 @@ public void invoke(V8Object v8Object, V8Array args) { private boolean mIsTerminateExecution; private int mApplicationState = STATE_NONE; + private ConcurrentLinkedQueue mTaskList = new ConcurrentLinkedQueue<>(); + protected JsThread(Context context) { super("JsThread"); @@ -742,6 +744,10 @@ public void postDestroyPage(Page page) { } } + public void addConfigurationNotifyInfo(RootView.ReloadPageConfigurationChangedInfo task) { + mTaskList.add(task); + } + public void loadPage(final Page page) { RuntimeLogManager.getDefault().logPageLoadStart(mAppInfo.getPackage(), page.getName()); mMainHandler.obtainMessage(RootView.MSG_LOAD_PAGE_JS_START, page).sendToTarget(); @@ -774,10 +780,38 @@ protected void onPostExecute(String[] contents) { postCreatePage(page, contents[0], jsUri, contents[1]); Log.d(TAG, "loadPage onPostExecute uri=" + jsUri + " result=" + result); + notifyReloadPageConfigurationChanged(page); } }); } + private void notifyReloadPageConfigurationChanged(Page currentPage) { + if (mTaskList != null && !mTaskList.isEmpty()) { + Iterator iterator = mTaskList.iterator(); + while (iterator.hasNext()) { + RootView.ReloadPageConfigurationChangedInfo pageConfigurationChangedInfo = (RootView.ReloadPageConfigurationChangedInfo)(iterator.next()); + if (pageConfigurationChangedInfo != null && !pageConfigurationChangedInfo.isConsumed()) { + if (pageConfigurationChangedInfo.getPage().pageId == currentPage.pageId) { + if (pageConfigurationChangedInfo.isLocaleChanged()) { + postNotifyConfigurationChanged(currentPage, CONFIGURATION_TYPE_LOCALE); + } + if (pageConfigurationChangedInfo.isThemeModeChanged()) { + postNotifyConfigurationChanged(currentPage, CONFIGURATION_TYPE_THEME_MODE); + } + if (pageConfigurationChangedInfo.isOrientationChanged()) { + postNotifyConfigurationChanged(currentPage, CONFIGURATION_TYPE_ORIENTATION); + } + if (pageConfigurationChangedInfo.isScreenSizeChanged()) { + postNotifyConfigurationChanged(currentPage, CONFIGURATION_TYPE_SCREEN_SIZE); + } + pageConfigurationChangedInfo.setConsumed(true); + iterator.remove(); + } + } + } + } + } + private void parseStyleSheets(String css, Page page) { if (TextUtils.isEmpty(css)) { return;