为什么使用setFrame无效?

本文解决了在使用Auto Layout时遇到的颜色设置问题。通过禁用Auto Layout,成功为视图设置了棕色背景色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

self.showTiming.frame = CGRectMake(0.0, 0.0, 10.0, 360.0);//这个无效

[self.showTiming setBackgroundColor:[UIColor brownColor]];//这个有效


解决方案:使用了auto layout 吧  把勾去掉应该就可以了 

// frameworks/base/services/core/java/com/android/server/wm/ParallelSession.java package com.android.server.wm; import android.annotation.NonNull; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.content.res.XmlResourceParser; import android.graphics.Rect; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.SparseArray; import android.util.Xml; import android.view.DisplayInfo; import android.view.WindowManager; import android.view.InputChannel; import com.android.server.input.InputManagerService; import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.concurrent.CopyOnWriteArrayList; import java.util.HashSet; import java.util.Set; import com.android.server.wm.ActivityRecord.State; /** * 管理平行视界会话,处理主副屏Activity的生命周期同步和布局 */ public class ParallelSession { private static final String TAG = "ParallelSession_wangw"; private static final boolean DEBUG = true; // 全局会话存储(按任务ID索引) private static final SparseArray<ParallelSession> sSessions = new SparseArray<>(); // 平行应用映射(包名 -> 副屏Activity类名) private static final ArrayMap<String, String> sParallelApps = new ArrayMap<>(); private final int mTaskId; private ActivityRecord mPrimaryActivity; // 主屏活动 private ActivityRecord mSecondaryActivity; // 副屏活动 private float mSplitRatio = 0.4f; // 分屏比例(默认50%) private WindowState mPrimaryWindow; // 主屏窗口 private WindowState mSecondaryWindow; // 副屏窗口 // 生命周期监听器接口(用于状态同步) public interface LifecycleListener { void onStateChanged(ActivityRecord activity, State state); void onDestroyed(ActivityRecord activity); void onConfigurationChanged(ActivityRecord activity, Configuration newConfig); } // 线程安全的生命周期监听器列表 private final CopyOnWriteArrayList<LifecycleListener> mLifecycleListeners = new CopyOnWriteArrayList<>(); public ParallelSession(ActivityRecord primary) { mTaskId = primary.getTask().mTaskId; mPrimaryActivity = primary; sSessions.put(primary.getTask().mTaskId, this); if (DEBUG) Log.d(TAG, "Created new ParallelSession for task: " + primary.getTask().mTaskId +", primary = "+primary.toString()); } public ParallelSession(int taskId, ActivityRecord primary) { mTaskId = taskId; mPrimaryActivity = primary; sSessions.put(taskId, this); Log.i(TAG, "创建平行会话,任务ID: " + taskId); } // 设置副屏活动 public void setSecondaryActivity(ActivityRecord secondary) { if (mSecondaryActivity != null) { Log.w(TAG, "Secondary activity already set!"); return; } mSecondaryActivity = secondary; linkActivities(); if (DEBUG) Log.d(TAG, "Secondary activity set: " + secondary); } private void linkActivities() { // 绑定生命周期事件 if (DEBUG) Log.d(TAG, "linkActivities"); mPrimaryActivity.addLifecycleListener(new LifecycleListener() { @Override public void onStateChanged(ActivityRecord activity, State state) { if (DEBUG) Log.d(TAG, "linkActivities mPrimaryActivity onStateChanged"); if (state == ActivityRecord.State.PAUSED && mSecondaryActivity != null) { if (DEBUG) Log.d(TAG, "Primary paused, pausing secondary"); // 使用任务调度暂停副屏活动 //mSecondaryActivity.pause(); //mSecondaryActivity.getTask().schedulePauseActivity(mSecondaryActivity); } else if (state == ActivityRecord.State.RESUMED && mSecondaryActivity != null) { if (DEBUG) Log.d(TAG, "Primary resumed, resuming secondary"); // 使用系统服务恢复副屏活动 mSecondaryActivity.getTask().resumeTopActivityUncheckedLocked(null, null); //mSecondaryActivity.resume(); } handleFocusChange(mPrimaryWindow); } @Override public void onConfigurationChanged(ActivityRecord activity, Configuration newConfig) { if (DEBUG) Log.d(TAG, "linkActivities mPrimaryActivity onConfigurationChanged"); } @Override public void onDestroyed(ActivityRecord activity) { if (DEBUG) Log.d(TAG, "linkActivities mPrimaryActivity onDestroyed"); if (mSecondaryActivity != null && !mSecondaryActivity.finishing) { if (DEBUG) Log.d(TAG, "Primary destroyed, finishing secondary"); // 使用安全销毁方法 mSecondaryActivity.destroyIfPossible("Primary destroyed"); //mSecondaryActivity.finishIfPossible("Primary destroyed", true); } sSessions.remove(activity.getTask().mTaskId); } }); // 副屏关闭时同步主屏 mSecondaryActivity.addLifecycleListener(new LifecycleListener() { @Override public void onStateChanged(ActivityRecord activity, State state) { if (DEBUG) Log.d(TAG, "linkActivities mSecondaryActivity onStateChanged"); handleFocusChange(mSecondaryWindow); } @Override public void onConfigurationChanged(ActivityRecord activity, Configuration newConfig) { if (DEBUG) Log.d(TAG, "linkActivities mSecondaryActivity onConfigurationChanged"); } @Override public void onDestroyed(ActivityRecord activity) { if (DEBUG) Log.d(TAG, "linkActivities mSecondaryActivity onDestroyed"); if (mPrimaryActivity != null && !mPrimaryActivity.finishing) { if (DEBUG) Log.d(TAG, "Secondary destroyed, finishing primary"); // 使用安全销毁方法 mPrimaryActivity.destroyIfPossible("Secondary destroyed"); //mPrimaryActivity.finishIfPossible("Secondary destroyed", true); } sSessions.remove(mPrimaryActivity.getTask().mTaskId); } }); } // 计算主屏显示区域 public Rect getPrimaryBounds(DisplayContent display) { if (DEBUG) Log.d(TAG, "getPrimaryBounds"); if (display == null) { Log.w(TAG, "Null display for primary bounds"); return new Rect(0, 0, 1080, 1920); // 默认值 } DisplayInfo info = display.getDisplayInfo(); Rect bounds = new Rect(0, 0, info.logicalWidth, info.logicalHeight); bounds.left = (int) (bounds.width() * mSplitRatio); // 按比例分割 return bounds; } // 计算副屏显示区域 public Rect getSecondaryBounds(DisplayContent display) { if (DEBUG) Log.d(TAG, "getSecondaryBounds"); if (display == null) { Log.w(TAG, "Null display for secondary bounds"); return new Rect(0, 0, 1080, 1920); // 默认值 } DisplayInfo info = display.getDisplayInfo(); Rect bounds = new Rect(0, 0, info.logicalWidth, info.logicalHeight); bounds.right = (int) (bounds.width() * mSplitRatio); // 按比例分割 return bounds; } public void setSplitRatio(float ratio) { if (DEBUG) Log.d(TAG, "setSplitRatio"); mSplitRatio = Math.max(0.2f, Math.min(0.8f, ratio)); if (mPrimaryActivity != null && mPrimaryActivity.getWindow() != null) { mPrimaryActivity.getTask().reparent(null, true); } if (mSecondaryActivity != null && mSecondaryActivity.getWindow() != null) { mSecondaryActivity.getTask().reparent(null, true); } } public static boolean shouldOpenInSecondary(ActivityRecord caller, ActivityInfo targetInfo) {//控制是否在第二界面打开 if (DEBUG) Log.d(TAG, "shouldOpenInSecondary, caller.packageName = "+caller.packageName+", targetInfo.targetActivity = "+targetInfo.targetActivity); return "com.jingdong.app.mall".equals(caller.packageName) || "com.alibaba.android.rimet".equals(caller.packageName); /* if (caller == null || !sParallelApps.containsKey(caller.packageName)) { return false; } String expectedActivity = sParallelApps.get(caller.packageName); return expectedActivity.equals(targetInfo.targetActivity) || expectedActivity.equals(targetInfo.name); */ } /* public static void loadConfigFromFile(File configFile) { if (!configFile.exists()) { Log.w(TAG, "Parallel config file not found: " + configFile); return; } try (FileInputStream fis = new FileInputStream(configFile)) { XmlResourceParser parser = Xml.newPullParser(); parser.setInput(fis, "UTF-8"); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) continue; final String tagName = parser.getName(); if ("parallel-apps".equals(tagName)) { parseParallelApps(parser); } } } catch (IOException | XmlPullParserException e) { Log.e(TAG, "Error loading parallel config", e); } } private static void parseParallelApps(XmlPullParser parser) throws IOException, XmlPullParserException { sParallelApps.clear(); int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type != XmlPullParser.START_TAG) continue; if ("app".equals(parser.getName())) { String pkg = parser.getAttributeValue(null, "package"); String secondary = parser.getAttributeValue(null, "secondary"); if (pkg != null && secondary != null) { sParallelApps.put(pkg, secondary); if (DEBUG) Log.i(TAG, "Added parallel app: " + pkg + " -> " + secondary); } } } } */ // 注册主屏窗口 public void registerPrimaryWindow(WindowState win) { mPrimaryWindow = win; if (DEBUG) Log.d(TAG, "注册主屏窗口: " + win); } public void registerSecondaryWindow(WindowState win) { mSecondaryWindow = win; if (DEBUG) Log.d(TAG, "Registered secondary window: " + win); } // 处理焦点变化(确保只有一个窗口获得焦点) public void handleFocusChange(WindowState focused) { if (DEBUG) Log.d(TAG, "handleFocusChange"); if (focused == null) return; if (focused == mPrimaryWindow && mSecondaryWindow != null) { //mSecondaryWindow.onSetFocused(false); // 取消副屏焦点 //focused.mWmService.mInputMonitor.setInputFocusLw(mSecondaryWindow, false); mSecondaryWindow.getDisplayContent().getInputMonitor().setInputFocusLw(mSecondaryWindow, false); } else if (focused == mSecondaryWindow && mPrimaryWindow != null) { //mPrimaryWindow.onSetFocused(false); // 取消主屏焦点 //focused.mWmService.mInputMonitor.setInputFocusLw(mPrimaryWindow, false); mPrimaryWindow.getDisplayContent().getInputMonitor().setInputFocusLw(mPrimaryWindow, false); } focused.mWmService.updateFocusedWindowLocked( WindowManagerService.UPDATE_FOCUS_NORMAL, true ); } // 添加窗口令牌映射 /* private final ArrayMap<IBinder, ActivityRecord> mTokenToRecord = new ArrayMap<>(); public void registerWindowToken(IBinder token, ActivityRecord ar) { mTokenToRecord.put(token, ar); } public ActivityRecord getRecordForToken(IBinder token) { return mTokenToRecord.get(token); } */ // 添加生命周期监听器 public void addLifecycleListener(LifecycleListener listener) { if (DEBUG) Log.d(TAG, "addLifecycleListener"); mLifecycleListeners.add(listener); } // 状态变化通知 public void onStateChanged(ActivityRecord activity, State state) { if (DEBUG) Log.d(TAG, "onStateChanged"); for (LifecycleListener listener : mLifecycleListeners) { listener.onStateChanged(activity, state); } } public void onDestroyed(ActivityRecord activity) { if (DEBUG) Log.d(TAG, "onDestroyed"); for (LifecycleListener listener : mLifecycleListeners) { listener.onDestroyed(activity); } if (activity == mPrimaryActivity || activity == mSecondaryActivity) { sSessions.remove(mTaskId); } } public void onConfigurationChanged(ActivityRecord activity, Configuration newConfig) { if (DEBUG) Log.d(TAG, "onConfigurationChanged"); for (LifecycleListener listener : mLifecycleListeners) { listener.onConfigurationChanged(activity, newConfig); } } // 销毁会话 public void destroy() { sSessions.remove(mTaskId); Log.i(TAG, "销毁平行会话,任务ID: " + mTaskId); } // 获取指定任务的会话 public static ParallelSession getSessionForTask(int taskId) { if (DEBUG) Log.d(TAG, "getSessionForTask"); return sSessions.get(taskId); } public static boolean isParallelSessionActive(int taskId) { if (DEBUG) Log.d(TAG, "isParallelSessionActive"); return sSessions.get(taskId) != null; } public ActivityRecord getPrimaryActivity() { if (DEBUG) Log.d(TAG, "getPrimaryActivity = "+mPrimaryActivity.toString()); return mPrimaryActivity; } public ActivityRecord getSecondaryActivity() { if (DEBUG) Log.d(TAG, "getSecondaryActivity = "+mSecondaryActivity.toString()); return mSecondaryActivity; } public WindowState getPrimaryWindow() { if (DEBUG) Log.d(TAG, "getPrimaryWindow = "+mPrimaryWindow.toString()); return mPrimaryWindow; } public WindowState getSecondaryWindow() { if (DEBUG) Log.d(TAG, "getSecondaryWindow = "+mSecondaryWindow.toString()); return mSecondaryWindow; } /* public interface ActivityLifecycleListener { void onStateChanged(ActivityRecord activity, State state); default void onDestroyed(ActivityRecord activity); void onConfigurationChanged(ActivityRecord activity, Configuration newConfig); } */ /** * 平行视界完整工作流程 入口触发:当主Activity启动副Activity时,ActivityStarter 检测到白名单匹配 会话创建:创建 ParallelSession 并关联主Activity 副屏创建:创建副屏任务栈,将目标Activity放入副屏 布局阶段:DisplayPolicy 为两个Activity计算分屏布局 输入路由:InputDispatcher 根据触摸位置分发到正确窗口 生命周期同步:通过监听器实现主副屏状态同步 新增 ParallelSession.java 新增类 会话管理核心 管理活动、窗口、布局和生命周期同步 DisplayPolicy.java 修改 layoutWindowLw() 方法 覆盖布局逻辑,应用平行视界布局 WindowManagerService.java 修改 添加 ParallelInputMonitor 处理触摸事件重定向 WindowState.java 修改 onSetFocused() 和 attach() 处理焦点管理和窗口注册 ActivityRecord.java 修改 生命周期方法覆盖 实现状态同步和配置变更通知 ActivityStarter.java 修改 execute() 方法 添加平行会话启动逻辑 新增 /system/etc/parallel_apps.xml 配置文件 应用配置列表 定义支持平行视界的应用及其分屏比例 */ } 这是平行视界的工具类 public void layoutWindowLw(WindowState win, WindowState attached, DisplayFrames displayFrames) { if (win.skipLayout()) { return; } android.util.Log.d("ParallelSession_wangw", "layoutWindowLw "); // 获取当前Display if(win != null) { DisplayContent display = win.getDisplayContent(); if (display != null) { // 平行视界处理 ActivityRecord ar = win.getActivityRecord(); if (ar != null) { ParallelSession session = ParallelSession.getSessionForTask(ar.getTask().mTaskId); if (session != null) { android.util.Log.d("ParallelSession_wangw", "layoutWindowLw win.setFrames"); // 设置窗口边界 Rect bounds = (ar == session.getPrimaryActivity()) ? session.getPrimaryBounds(display) : session.getSecondaryBounds(display); /* // 设置所有相关布局区域 frame.set(bounds); // 调整窗口特性 win.setForceHideNonSystemOverlayWindowIfNeede(true); win.setCanBeSeen(false); // 设置窗口位置 win.setFrame(bounds); win.setParallelSession(true); */ /* // === 修改点1: 使用正确的WindowFrames对象 === // 获取窗口当前的WindowFrames对象 WindowFrames winFrames = win.getWindowFrames(); // 设置所有相关布局区域 winFrames.mFrame.set(bounds); // 主窗口区域 winFrames.mDisplayFrame.set(bounds); // 显示区域 winFrames.mParentFrame.set(bounds); // 父容器区域 */ // 替代 setWindowFrames() ClientWindowFrames tmpFrames = new ClientWindowFrames(); tmpFrames.frame.set(bounds); tmpFrames.displayFrame.set(bounds); tmpFrames.parentFrame.set(bounds); //win.mWmService.mWindowPlacerLocked.requestTraversal(); //win.mHidden = true; win.setFrames(tmpFrames, bounds.width(), bounds.height()); // === 修改点2: 使用标准API设置窗口状态 === // 1. 强制隐藏非系统覆盖层窗口 - 通过设置私有标志位 //win.mAttrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; // 2. 设置窗口隐藏状态 - 通过系统服务API //win.mWmService.mWindowPlacerLocked.requestTraversal(); //win.mHidden = true; // 使用setHidden替代setCanBeSeen // === 修改点3: 使用setFrames设置窗口位置 === //win.setFrames(winFrames, winFrames.mFrame.width(), winFrames.mFrame.height()); //win.setWindowFrames(winFrames); // === 修改点4: 添加自定义标记的替代方案 === // 如果需要标记平行视界状态,应在WindowState中添加自定义字段 // 这里使用临时方案:在WindowToken中存储状态 //win.mToken.parallelSession = true; Rect bounds_other = (ar != session.getPrimaryActivity()) ? session.getPrimaryBounds(display) : session.getSecondaryBounds(display); ClientWindowFrames tmpFrames_other = new ClientWindowFrames(); tmpFrames_other.frame.set(bounds_other); tmpFrames_other.displayFrame.set(bounds_other); tmpFrames_other.parentFrame.set(bounds_other); //win.mWmService.mWindowPlacerLocked.requestTraversal(); //win.mHidden = true; win.setFrames(tmpFrames_other, bounds_other.width(), bounds_other.height()); return; } } } } 这是设置平行视界左右窗口的位置 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, ActivityOptions options, Task inTask, TaskFragment inTaskFragment, @BalCode int balCode, NeededUriGrants intentGrants, int realCallingUid) { int result = START_CANCELED; Task startedActivityRootTask = null; //wfs add 20250712 @{ if((sourceRecord==null||(sourceRecord!=null&&!"com.tmall.wireless".equals(sourceRecord.mActivityComponent.getClassName())))&&"com.ali.user.mobile.login.ui.UserLoginActivity".equals(r.mActivityComponent.getClassName())&&!"com.tmall.wireless".equals(getTopPkg())&&!"com.taobao.taobao".equals(getTopPkg())){ android.util.Log.d("wfswfs333"," r.mActivityComponent.getClassName()::"+r.mActivityComponent.getClassName()); return START_CANCELED; } //wfs add 20250712 @} // ===== 平行视界拦截逻辑 ===== android.util.Log.d("ParallelSession_wangw", "startActivityUnchecked "); try { if (shouldStartParallel(mStartActivity)) { ActivityRecord callerRecord = (sourceRecord != null) ? sourceRecord : mStartActivity; android.util.Log.d("ParallelSession_wangw", "startActivityUnchecked callerRecord = "+sourceRecord != null ? "sourceRecord" : "mStartActivity"); if (mStartActivity != null) android.util.Log.d("ParallelSession_wangw", "startActivityUnchecked mStartActivity.packageName = "+mStartActivity.packageName); if (callerRecord != null && mService != null) { android.util.Log.d("ParallelSession_wangw", "startActivityUnchecked callerRecord != null; callerRecord.packageName = "+callerRecord.packageName); int callerTaskId = callerRecord.getTask().mTaskId; // 检查是否已有平行会话 ParallelSession session = ParallelSession.getSessionForTask(callerTaskId); TaskDisplayArea taskDisplayArea = mPreferredTaskDisplayArea != null ? mPreferredTaskDisplayArea : mRootWindowContainer.getDefaultTaskDisplayArea(); // 检查是否应该启动到副屏 if (session == null && ParallelSession.shouldOpenInSecondary(callerRecord, r.info)) { android.util.Log.d("ParallelSession_wangw", "startActivityUnchecked new ParallelSession"); // 创建新的平行会话 session = new ParallelSession(callerRecord); //mService.setParallelSession(session); //// 创建副屏任务栈 Task secondaryTask = taskDisplayArea.createRootTask( WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, // 分屏副屏模式 ACTIVITY_TYPE_STANDARD, // 标准Activity类型 true // 置于顶部 ); // 设置任务属性 secondaryTask.setIntent(r); r.reparent(secondaryTask, secondaryTask.getChildCount() /* position */, "parallel_launch"); /* // ===== 修改点1:使用Task.Builder创建任务 ===== // 创建Task.Builder实例 final Task.Builder builder = new Task.Builder(mService); // 设置关键属性: builder.setParent(taskDisplayArea) // 父容器 .setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) // 分屏副屏模式 .setActivityType(ACTIVITY_TYPE_STANDARD) // 标准Activity类型 .setOnTop(true) // 置于顶部 //.setActivity(r) // 关联的ActivityRecord .setIntent(r.intent); // Intent // 构建任务实例 Task secondaryTask = builder.build(); // 将ActivityRecord添加到新任务中 secondaryTask.addChild(r, secondaryTask.getChildCount()); // 设置ActivityRecord的任务 r.reparent(secondaryTask, secondaryTask.getChildCount(), "parallel_launch"); // ===== 修改结束 ===== */ // 关联到平行会话 session.setSecondaryActivity(r); //if (DEBUG) { android.util.Log.d(TAG, "Launching activity in parallel mode: " + r + " in task: " + secondaryTask); //} } // 已有会话时处理 else if (session != null && session.getSecondaryActivity() == null) { android.util.Log.d("ParallelSession_wangw", "startActivityUnchecked session != null"); // 已有主屏但无副屏的情况 // 创建副屏根任务 Task secondaryTask = taskDisplayArea.createRootTask( WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true ); // 设置任务属性 secondaryTask.setIntent(r); // ===== 关键修改使用 reparent() 将 Activity 移动到新任务 ===== r.reparent(secondaryTask, secondaryTask.getChildCount(), "parallel_launch"); /* // ===== 修改点2:同样使用Task.Builder创建任务 ===== final Task.Builder builder = new Task.Builder(mService); builder.setParent(taskDisplayArea) .setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) .setActivityType(ACTIVITY_TYPE_STANDARD) .setOnTop(true) //.setActivity(r) .setIntent(r.intent); Task secondaryTask = builder.build(); // 将ActivityRecord添加到新任务中 secondaryTask.addChild(r, secondaryTask.getChildCount()); // 设置ActivityRecord的任务 r.reparent(secondaryTask, secondaryTask.getChildCount(), "parallel_launch"); // ===== 修改结束 ===== */ session.setSecondaryActivity(r); } else { android.util.Log.d("ParallelSession_wangw", "startActivityUnchecked Failed to Launching activity in parallel mode"); } } } } catch (Exception e) { android.util.Log.e("ParallelSession_wangw", "Failed to create parallel session", e); } 这是启动平行视界的地方 但这样改了之后,mPrimaryActivity不显示了,只显示mSecondaryActivity是什么原因怎么解决
最新发布
07-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值