Implementation Method | User Experience | Resource Consumption | Implementation Logic |
Good. When you switch between live streaming rooms, a black screen is displayed before the new video appears. | No additional resource consumption. | Simple. No additional logic. | |
Slightly better. When you switch between live streaming rooms, a fixed placeholder image of the corresponding anchor is displayed before the new video appears. | Slightly higher. A placeholder image needs to be additionally stored for each anchor and loaded on the client. | Slightly complex. Asynchronous loading of placeholder images is additionally required before switching. | |
Best. When you switch between live streaming rooms, the videos of the current and next anchors are smoothly displayed. | Higher. Two streams need to be pulled concurrently in the list. After you enter a live streaming room, only 1 stream needs to be pulled. | More complex. Multiple instances are required, and the audio and video pulling of each instance needs to be controlled. |

let src = TRTCSwitchRoomConfig()// Generate the corresponding room ID and room entry credential according to business needs. In this example, generate the room entry credential on the client. For online businesses, obtain the information from the backend.src.strRoomId = strRoomIdsrc.userSig = GenerateTestUserSig.genTestUserSig(identifier: userId) as StringtrtcCloud.switchRoom(src)

bgView = UIImageView(frame: self.view.bounds)// The image should be the placeholder image for the corresponding live streaming room. Business personnel should obtain the image in advance.bgView.image = UIImage(named: "1.png")bgView.contentMode = .scaleAspectFillbgView.translatesAutoresizingMaskIntoConstraints = falseself.view.insertSubview(bgView, at: 0)NSLayoutConstraint.activate([bgView.topAnchor.constraint(equalTo: view.topAnchor),bgView.bottomAnchor.constraint(equalTo: view.bottomAnchor),bgView.leadingAnchor.constraint(equalTo: view.leadingAnchor),bgView.trailingAnchor.constraint(equalTo: view.trailingAnchor),])
DispatchQueue.main.async {UIView.transition(with: self.bgView,duration: 0,options: .transitionCrossDissolve,animations: {// Business personnel switches the corresponding placeholder image.self.bgView.image = UIImage(named: strRoomId)}, completion: nil)}let src = TRTCSwitchRoomConfig()// Generate the corresponding room ID and room entry credential according to business needs. In this example, generate the room entry credential on the client. For online businesses, obtain the information from the backend.src.strRoomId = strRoomIdsrc.userSig = GenerateTestUserSig.genTestUserSig(identifier: userId) as StringtrtcCloud.switchRoom(src)
// Pull video streams.func onUserVideoAvailable(_ userId: String, available: Bool) {if available {trtcCloud.startRemoteView(userId, streamType: .big, view: view)} else {trtcCloud.stopRemoteView(userId, streamType: .big)}}// When the first video frame starts rendering, switch the placeholder image to the background and display the video.func onFirstVideoFrame(_ userId: String, streamType: TRTCVideoStreamType, width: Int32, height: Int32) {// Adjust the sequence of the background image and the video rendering control as needed.self.view.exchangeSubview(at: 1, withSubviewAt: 0)}


import Foundationimport ObjectiveCimport TXLiteAVSDK_Professional@objc protocol SubCloudHelperDelegate : NSObjectProtocol {@objc optional func onUserVideoAvailableWithSubId(subId: Int, userId: String, available: Bool)}class SubCloudHelper:NSObject,TRTCCloudDelegate {var trtcCloud: TRTCCloud!var subId: Int!weak var delegate : SubCloudHelperDelegate? = nilfunc initWithSubId(subId: Int, trtcIns: TRTCCloud) {self.subId = subIdself.trtcCloud = trtcInsself.trtcCloud.addDelegate(self)}func getCloud()->TRTCCloud {return trtcCloud}func onUserVideoAvailable(_ userId: String, available: Bool) {if self.delegate?.onUserVideoAvailableWithSubId?(subId: subId, userId: userId, available: available) == nil {return}}}
let trtcCloud = TRTCCloud()let subCloudHelper = SubCloudHelper()override func viewDidLoad() {super.viewDidLoad()subCloudHelper.initWithSubId(subId: 0, trtcIns: trtcCloud.createSub())subCloudHelper.delegate = self}
private var atRoom: Bool = falsevar pageViewController: UIPageViewController!var pageZero: UIViewController!var pageOne: UIViewController!var pageTwo: UIViewController!var pages: [UIViewController] = []var curPageIdx = 0var curIsSub = falsefunc setupPages() {pageViewController = UIPageViewController(transitionStyle: .scroll,navigationOrientation: .vertical)pageViewController.dataSource = selfpageViewController.delegate = selfaddChild(pageViewController)view.addSubview(pageViewController.view)pageViewController.didMove(toParent: self)// pagespageZero = UIViewController()pageZero.view.backgroundColor = .blackpageOne = UIViewController()pageOne.view.backgroundColor = .blackpageTwo = UIViewController()pageTwo.view.backgroundColor = .blackpages = [pageZero, pageOne, pageTwo]pageViewController.setViewControllers([pages[curPageIdx]], direction: .forward, animated: false)}
// Obtain the next/previous page.func getShowPage(isNext: Bool) -> UIViewController {var newPageIdx = 0if isNext {newPageIdx = curPageIdx + 1} else {newPageIdx = curPageIdx - 1}if newPageIdx >= pages.count {newPageIdx = 0} else if newPageIdx < 0 {newPageIdx = pages.count - 1}return pages[newPageIdx]}extension RtcDuplexVC: UIPageViewControllerDataSource {func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {return getShowPage(isNext: false)}func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {return getShowPage(isNext: true)}}
// The primary instance enters the room.// Replace sdkAppId, roomID, strRoomId, userId, and userSig based on actual business needs.// In this example, generate userSig on the client. For online businesses, obtain the information from the backend.let params = TRTCParams()params.sdkAppId = UInt32(SDKAppID)params.roomId = 0params.strRoomId = strRoomIdLst.first ?? "1"params.userId = userIdparams.role = .anchorparams.userSig = GenerateTestUserSig.genTestUserSig(identifier: userId) as StringtrtcCloud.addDelegate(self)trtcCloud.enterRoom(params, appScene: .LIVE)// The sub-instance preloads and enters the next room.// Replace sdkAppId, roomID, strRoomId, userId, and userSig based on actual business needs.// In this example, generate userSig on the client. For online businesses, obtain the information from the backend.let subParams = TRTCParams()subParams.sdkAppId = UInt32(SDKAppID)subParams.roomId = 0subParams.strRoomId = strRoomIdLst[1]subParams.userId = userIdsubParams.role = .anchorsubParams.userSig = GenerateTestUserSig.genTestUserSig(identifier: userId) as StringsubCloudHelper.trtcCloud.enterRoom(subParams, appScene: .LIVE)subCloudHelper.trtcCloud.muteAllRemoteAudio(true)
func getPageByIdx(isNext: Bool) -> UIViewController {var newPageIdx = curPageIdxif isNext {newPageIdx += 1}if newPageIdx >= pages.count {newPageIdx = 0}return pages[newPageIdx]}extension RtcDuplexVC: TRTCCloudDelegate {func onUserVideoAvailable(_ userId: String, available: Bool) {if available {trtcCloud.startRemoteView(userId, streamType: .big, view: getPageByIdx(isNext: curIsSub).view)} else {trtcCloud.stopRemoteView(userId, streamType: .big)}}}extension RtcDuplexVC: SubCloudHelperDelegate {func onUserVideoAvailableWithSubId(subId: Int, userId: String, available: Bool) {if available {subCloudHelper.trtcCloud.startRemoteView(userId, streamType: .big, view: getPageByIdx(isNext: !curIsSub).view)} else {subCloudHelper.trtcCloud.stopRemoteView(userId, streamType: .big)}}}
func updateCurRoomIdx(isNext: Bool) {if isNext {curRoomIdx += 1if curRoomIdx >= strRoomIdLst.count {curRoomIdx = 0}} else {curRoomIdx -= 1if curRoomIdx < 0 {curRoomIdx = strRoomIdLst.count - 1}}}// Here, you need to switch the room ID based on the actual business logic.func updateNewRoom(isNext: Bool) {var newRoomIdx = 0if isNext{newRoomIdx = curRoomIdx + 1} else {newRoomIdx = curRoomIdx - 1}if newRoomIdx >= strRoomIdLst.count {newRoomIdx = 0} else if newRoomIdx < 0 {newRoomIdx = strRoomIdLst.count - 1}let newRoomStrId = strRoomIdLst[newRoomIdx]let src = TRTCSwitchRoomConfig()src.strRoomId = newRoomStrIdsrc.userSig = GenerateTestUserSig.genTestUserSig(identifier: userId) as Stringif curIsSub {trtcCloud.switchRoom(src)trtcCloud.muteAllRemoteAudio(true)} else {subCloudHelper.trtcCloud.switchRoom(src)subCloudHelper.trtcCloud.muteAllRemoteAudio(true)}}extension RtcDuplexVC: UIPageViewControllerDelegate {func pageViewController(_ pageViewController: UIPageViewController,didFinishAnimating finished: Bool,previousViewControllers: [UIViewController],transitionCompleted completed: Bool) {if completed {guard let currentVC = pageViewController.viewControllers?.first else {return}if let index = pages.firstIndex(of: currentVC) {// Obtain the basis for determining whether the user scrolled up or down.let iden = index - curPageIdx// Update the index of the currently displayed page.curPageIdx = index// Scroll down.if iden == 1 || iden == -2 {// Update the index of the current room.updateCurRoomIdx(isNext: true)// Update the instance of the currently displayed page.curIsSub.toggle()// Update the room.updateNewRoom(isNext: true)}// Scroll up.if iden == -1 || iden == 2 {// Update the room.updateNewRoom(isNext: false)// Update the index of the current room.updateCurRoomIdx(isNext: false)// Update the instance of the currently displayed page.curIsSub.toggle()trtcCloud.muteAllRemoteAudio(true)subCloudHelper.trtcCloud.muteAllRemoteAudio(true)}// Unmute the current room.if curIsSub {subCloudHelper.trtcCloud.muteAllRemoteAudio(false)} else {trtcCloud.muteAllRemoteAudio(false)}}}}}

// Handle the logic for entering a live streaming room.@objc func enterBtnClick() {// Hide the UI component in the vertical scrolling list.self.enterBtn.isHidden = true// Display the UI component after the user enters a live streaming room.self.exitBtn.isHidden = false// ...self.atRoom = true// Forbid vertical scrolling once the user enters a live streaming room.pageViewController.dataSource = nil// Stop preloading.if curIsSub{trtcCloud.muteAllRemoteVideoStreams(true)} else {subCloudHelper.trtcCloud.muteAllRemoteAudio(true)}}// Handle the logic for exiting a live streaming room.@objc func exitBtnClick() {// Hide the UI component in a live streaming room.self.enterBtn.isHidden = false// Display the UI component in the vertical scrolling list.self.exitBtn.isHidden = trueself.atRoom = false// Restore vertical scrolling once the user enters the vertical scrolling list.pageViewController.dataSource = self// Restore preloading.if curIsSub{trtcCloud.muteAllRemoteVideoStreams(false)} else {subCloudHelper.trtcCloud.muteAllRemoteAudio(false)}}
Implementation Method | User Experience | Resource Consumption | Implementation Logic |
Typically, while scrolling through the list, you cannot view 2 live streaming rooms simultaneously. The corresponding live streaming room is displayed only after the page is fully switched. In this case, placeholder images can be used to enhance user experience. | Only 1 stream in the list consumes traffic, and 1 video playback object is being used. | Simple. Set placeholder images as needed. | |
Better. You can enter 2 live streaming rooms simultaneously, and the next live streaming room is loaded in advance. While scrolling through the list, you can view both the current and next live streaming rooms simultaneously. | Two streams in the list consumes traffic, incurring 2 streams of fees, and 2 video playback objects are being used. | Complex. Multiple instances are required, and the audio and video pulling of each instance needs to be controlled. |

public class ScrollSwitchRoomActivity extends TRTCBaseActivity {PageAdapter mAdapter;public String[] mRoomIds;private TRTCCloud mTRTCCloud;private TXCloudVideoView mRemoteVideoView;private int mCurPos = -1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_scroll_switch_room);// Hide the title bar.getSupportActionBar().hide();mRoomIds = new String[]{"1231", "1232", "1233"};if (checkPermission()) {initView();}}@Overrideprotected void onPermissionGranted() {initView();}private void initView() {mAdapter = new PageAdapter(this, mRoomIds);ViewPager2 viewPager = findViewById(R.id.viewPager);viewPager.setAdapter(mAdapter);// Set the viewPager scrolling orientation.viewPager.setOrientation(ViewPager2.ORIENTATION_VERTICAL);// Set the viewPager preloading.viewPager.setOffscreenPageLimit(1);// Add a page switch listener.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {public void onPageSelected(int position) {Log.d("ScrollSwitchRoom", "onPageSelected: " + position);if (mCurPos == position) {return;}RecyclerView recyclerViewImpl = (RecyclerView) viewPager.getChildAt(0);// Exit the current room.exitRoom();// Enter the next room.View itemView = recyclerViewImpl.getChildAt(position);mRemoteVideoView = itemView.findViewById(R.id.txcvv_main_local);enterRoom(position);mCurPos = position;}});// Initialize your views heremTRTCCloud = TRTCCloud.sharedInstance(getApplicationContext());mTRTCCloud.addListener(mTRTCCloudListener);}private void enterRoom(int roomIdIndex) {TRTCCloudDef.TRTCParams mTRTCParams = new TRTCCloudDef.TRTCParams();mTRTCParams.sdkAppId = GenerateTestUserSig.SDKAPPID;mTRTCParams.userId = "123";mTRTCParams.strRoomId = mRoomIds[roomIdIndex];mTRTCParams.userSig = GenerateTestUserSig.genTestUserSig(mTRTCParams.userId);mTRTCParams.role = TRTCCloudDef.TRTCRoleAudience;mTRTCCloud.enterRoom(mTRTCParams, TRTCCloudDef.TRTC_APP_SCENE_LIVE);}private TRTCCloudListener mTRTCCloudListener = new TRTCCloudListener() {public void onEnterRoom(long result) {if (result == 0) {// Enter room success} else {// Enter room failed}}public void onExitRoom(int reason) {// Exit room}@Overridepublic void onUserVideoAvailable(String userId, boolean available) {super.onUserVideoAvailable(userId, available);if (available) {mTRTCCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, mRemoteVideoView);} else {mTRTCCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);}}public void onError(int errCode, String errMsg, Bundle extraInfo) {// print ErrorLog.e("ScrollSwitchRoom", "Error: " + errCode + " " + errMsg);}};private void exitRoom() {mTRTCCloud.stopAllRemoteView();mTRTCCloud.exitRoom();// mTRTCCloud.setListener(null);}public class PageAdapter extends RecyclerView.Adapter<PageAdapter.PageViewHolder> {private Context context;public String[] mRoomIds;public PageAdapter(Context context, String[] roomIds) {this.context = context;this.mRoomIds = roomIds;}public PageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(context).inflate(R.layout.item_scroll_page, parent, false);return new PageViewHolder(view);}public void onBindViewHolder(@NonNull PageViewHolder holder, int position) {TextView textView = holder.itemView.findViewById(R.id.tv_room_number);textView.setText(getString(R.string.switchroom_roomid) + ":" + mRoomIds[position]);}public int getItemCount() {return mRoomIds.length;}public int getItemViewType(int position) {return position;}class PageViewHolder extends RecyclerView.ViewHolder {PageViewHolder(@NonNull View itemView) {super(itemView);}}}@Overrideprotected void onDestroy() {super.onDestroy();exitRoom();}}
<?xml version="1.0" encoding="utf-8"?><androidx.viewpager2.widget.ViewPager2 xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/viewPager"android:layout_width="match_parent"android:layout_height="match_parent" />
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/item_layout"android:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:id="@+id/iv_placeholder"android:scaleType="centerCrop"android:background="@drawable/placeholder_img"android:layout_width="match_parent"android:layout_height="match_parent"/><com.tencent.rtmp.ui.TXCloudVideoViewandroid:id="@+id/txcvv_main_local"android:layout_width="match_parent"android:layout_height="match_parent" /><TextViewandroid:id="@+id/tv_room_number"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintEnd_toEndOf="@id/item_layout"app:layout_constraintStart_toStartOf="@id/item_layout" /></androidx.constraintlayout.widget.ConstraintLayout>

public class ScrollSwitchRoomDualActivity extends TRTCBaseActivity {PageAdapter mAdapter;public String[] mRoomIds;private TRTCCloud mTRTCCloud;private TRTCCloud mSubCloud;private TXCloudVideoView mRemoteVideoView;private TXCloudVideoView mSubRemoteVideoView;private Boolean mIsInMainRoom = null;private int mCurPos = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_scroll_switch_room);// Hide the title bar.getSupportActionBar().hide();mRoomIds = new String[]{"1231", "1232", "1233"};if (checkPermission()) {initView();}}@Overrideprotected void onPermissionGranted() {initView();}private void initView() {mAdapter = new PageAdapter(this,mRoomIds);ViewPager2 viewPager = findViewById(R.id.viewPager);viewPager.setAdapter(mAdapter);// Set the viewPager scrolling orientation.viewPager.setOrientation(ViewPager2.ORIENTATION_VERTICAL);// Set the viewPager preloading.viewPager.setOffscreenPageLimit(1);// Add a page switch listener.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {public void onPageSelected(int position) {Log.d("ScrollSwitchRoom", "onPageSelected: " + position);RecyclerView recyclerViewImpl = (RecyclerView) viewPager.getChildAt(0);if (mIsInMainRoom == null) {View itemView = recyclerViewImpl.getChildAt(position);mRemoteVideoView = itemView.findViewById(R.id.txcvv_main_local);View subItemView = recyclerViewImpl.getChildAt(position + 1);mSubRemoteVideoView = subItemView.findViewById(R.id.txcvv_main_local);enterRoom();mIsInMainRoom = true;} else {if (mIsInMainRoom) {mTRTCCloud.muteAllRemoteAudio(true);mSubCloud.muteAllRemoteAudio(false);} else {mTRTCCloud.muteAllRemoteAudio(false);mSubCloud.muteAllRemoteAudio(true);}if (position != (mRoomIds.length - 1)) {String roomId;TRTCCloud trtcCloud;if (mCurPos < position) {// Scroll up the screen.roomId = mRoomIds[position + 1];trtcCloud = mIsInMainRoom ? mTRTCCloud : mSubCloud;View itemView = recyclerViewImpl.getChildAt(position + 1);if (mIsInMainRoom) {mRemoteVideoView = itemView.findViewById(R.id.txcvv_main_local);} else {mSubRemoteVideoView = itemView.findViewById(R.id.txcvv_main_local);}} else {// Scroll down the screen.roomId = mRoomIds[position];trtcCloud = mIsInMainRoom ? mSubCloud : mTRTCCloud;View itemView = recyclerViewImpl.getChildAt(position);if (mIsInMainRoom) {mSubRemoteVideoView = itemView.findViewById(R.id.txcvv_main_local);} else {mRemoteVideoView = itemView.findViewById(R.id.txcvv_main_local);}}switchRoom(roomId, trtcCloud);}mIsInMainRoom = !mIsInMainRoom;}mCurPos = position;}});// Initialize your views heremTRTCCloud = TRTCCloud.sharedInstance(getApplicationContext());mSubCloud = mTRTCCloud.createSubCloud();}/*** Call a room entry only during initialization. To switch to a different room later, call switchRoom.*/private void enterRoom() {mTRTCCloud.addListener(mTRTCCloudListener);mSubCloud.addListener(mSubCloudListener);TRTCCloudDef.TRTCParams mTRTCParams = new TRTCCloudDef.TRTCParams();mTRTCParams.sdkAppId = GenerateTestUserSig.SDKAPPID;mTRTCParams.userId = "123";// mTRTCParams.roomId = Integer.parseInt(roomId);mTRTCParams.strRoomId = mRoomIds[0];mTRTCParams.userSig = GenerateTestUserSig.genTestUserSig(mTRTCParams.userId);mTRTCParams.role = TRTCCloudDef.TRTCRoleAudience;mTRTCCloud.enterRoom(mTRTCParams, TRTCCloudDef.TRTC_APP_SCENE_LIVE);mTRTCParams.strRoomId = mRoomIds[1];mSubCloud.muteAllRemoteAudio(true);mSubCloud.enterRoom(mTRTCParams, TRTCCloudDef.TRTC_APP_SCENE_LIVE);}private TRTCCloudListener mTRTCCloudListener = new TRTCCloudListener() {public void onEnterRoom(long result) {if (result == 0) {// Enter room success} else {// Enter room failed}}public void onExitRoom(int reason) {// Exit room}@Overridepublic void onUserVideoAvailable(String userId, boolean available) {super.onUserVideoAvailable(userId, available);if (available) {mTRTCCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, mRemoteVideoView);} else {mTRTCCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);}}public void onError(int errCode, String errMsg, Bundle extraInfo) {// print ErrorLog.e("ScrollSwitchRoom", "Error: " + errCode + " " + errMsg);}public void onSwitchRoom(long err, String errMsg) {// Switch room}};private TRTCCloudListener mSubCloudListener = new TRTCCloudListener() {public void onEnterRoom(long result) {if (result == 0) {// Enter room success} else {// Enter room failed}}public void onExitRoom(int reason) {// Exit room}@Overridepublic void onUserVideoAvailable(String userId, boolean available) {super.onUserVideoAvailable(userId, available);if (available) {mSubCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, mSubRemoteVideoView);} else {mSubCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);}}};private void exitRoom() {mTRTCCloud.stopAllRemoteView();mTRTCCloud.exitRoom();mTRTCCloud.setListener(null);mSubCloud.stopAllRemoteView();mSubCloud.exitRoom();mSubCloud.setListener(null);}private void switchRoom(String roomId, TRTCCloud trtcCloud) {TRTCCloudDef.TRTCSwitchRoomConfig config = new TRTCCloudDef.TRTCSwitchRoomConfig();// config.roomId = Integer.parseInt(roomId);config.strRoomId = roomId;trtcCloud.switchRoom(config);}public class PageAdapter extends RecyclerView.Adapter<PageAdapter.PageViewHolder> {private Context context;public String[] mRoomIds;public PageAdapter(Context context, String[] roomIds) {this.context = context;this.mRoomIds = roomIds;}public PageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(context).inflate(R.layout.item_scroll_page, parent, false);return new PageViewHolder(view);}public void onBindViewHolder(@NonNull PageViewHolder holder, int position) {TextView textView = holder.itemView.findViewById(R.id.tv_room_number);textView.setText(getString(R.string.switchroom_roomid) + ":" + mRoomIds[position]);}public int getItemCount() {return mRoomIds.length;}public int getItemViewType(int position) {return position;}class PageViewHolder extends RecyclerView.ViewHolder {PageViewHolder(@NonNull View itemView) {super(itemView);}}}@Overrideprotected void onDestroy() {super.onDestroy();exitRoom();}}
Feedback