【发布时间】:2020-01-14 11:38:09
【问题描述】:
我有一个聊天应用程序,它打开一个 Websocket 到服务器。该应用程序有 2 个模块 -
- chat sdk:处理连接加来回 消息传递。
- ui:处理适配器和视图
聊天 UI 位于 Activity 托管的片段上。
一切正常,但是当我决定对设备旋转使用持久性时,我遇到了问题。 当我旋转设备时,websocket 重新连接(这是正常的),活动被重新创建,片段也是如此。
在设备旋转和一些调试之后,我看到我的 messageList 正确填充了任何添加的项目(即消息文本),但不是 UI。当我从 EditText 键入文本并按发送时,该项目会正确显示在 UI 中,但是当我收到来自服务器的响应时,即使将消息添加到 messageList,UI 也不会更新。
我在类似的帖子中读到 RecyclerView 适配器在旋转后更新旧片段。是这样吗?如果是这种情况,为什么当我从 EditText 发送消息时它会正确显示,但从我的 WebSocket 的 onMessage 时却没有?
我试过"android:configChanges="screenSize|orientation|screenLayout" 没有任何结果。
我覆盖了 onConfigurationChanged 并强制适配器更新视图,但没有结果
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(messagesAdapter!=null){
messagesAdapter.notifyDataSetChanged();
}
}
我保存片段以在我的活动中恢复它
public class MessageActivity extends AppCompatActivity {
private MessageFragment fragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message);
if (savedInstanceState == null) {
fragment = MessageFragment.newInstance();
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment)
.commitNow();
}else{
fragment = (MessageFragment) getSupportFragmentManager().getFragment(savedInstanceState, "messageFragment");
}
}
@Override
public void onBackPressed() {
finishAffinity();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Save the fragment's instance
getSupportFragmentManager().putFragment(outState, "messageFragment", fragment);
}}
我还保存和检索我的消息列表
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
//saving the state of the chat
outState.putParcelableArrayList("messages", messageArrayList);
try {
Log.d(TAG, "messagelist in save instance " + messageArrayList.size());
}catch (NullPointerException e){
e.printStackTrace();
}
outState.putString("dialogId", messageArrayList.get(0).getDialogId());
}
来自 websocket 的 onMessage
@Override
public void onMessage(ArrayList<Message> data) {
if (!messageArrayList.isEmpty() && messageArrayList.get(messageArrayList.size() - 1).getServerMessageType() == Constants.TYPE_TYPING_ON) {
messageArrayList.remove(messageArrayList.size() - 1);
}
this.messageArrayList.addAll(data);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && isFragmentAttached) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (omiliaClient != null) {
updateUi(messageArrayList, omiliaClient.user2);
}
}
});
}
}
【问题讨论】:
-
既然您提到您的 UI 在屏幕旋转后更新/恢复。我需要了解从附加到 Api/websocket 的回调中接收新数据的代码 sn-p。您是否正确更新了数据集的同一实例,即
messageArrayList? -
添加了 sn-p 供您查看。但调试后我看到消息已正确添加到列表中
-
@sud007 你发给我的线程上选择的答案不是这样,但第二个答案是。但是下面的文基早点回答了。非常感谢。
标签: android android-recyclerview rotation fragment adapter