У меня есть приложение чата, которое открывает веб-сокет для сервера. Приложение имеет 2 модуля -
- chat sdk: который обрабатывает соединение плюс обмен сообщениями вперед и назад.
- ui: который обрабатывает адаптеры и представления
Пользовательский интерфейс чата находится на фрагменте, размещенном действием.
Все работало нормально, но когда я решил использовать постоянство при ротации устройства, у меня возникли проблемы. Когда я поворачиваю устройство, веб-сокет переподключается (что нормально), действие воссоздается, так же как и фрагмент.
После ротации устройства и некоторой отладки я увидел, что мой список сообщений правильно заполнен любыми добавленными элементами (ie текстами сообщений), но не пользовательским интерфейсом. Когда я набираю текст из EditText и нажимаю отправить, элемент правильно отображается в пользовательском интерфейсе, НО, когда я получаю ответ от сервера, пользовательский интерфейс не обновляется, даже если сообщение добавляется в messageList.
Я читал в похожих постах, что адаптер RecyclerView обновляет старый фрагмент после ротации. Это тот случай? И если это так, то почему, когда я отправляю сообщение из EditText, оно отображается правильно, но не из onMessage моего WebSocket?
Я пытался "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());
}
onMessage из websocket
@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);
}
}
});
}
}