Trying to speed up app startup & prevent blank screen

This commit is contained in:
Sylvain Berfini 2024-01-29 17:31:02 +01:00
parent b1d0554a07
commit ddd614acd0
15 changed files with 53 additions and 77 deletions

View file

@ -36,6 +36,7 @@ import org.linphone.core.CorePreferences
import org.linphone.core.Factory
import org.linphone.core.LogCollectionState
import org.linphone.core.LogLevel
import org.linphone.core.tools.Log
@MainThread
class LinphoneApplication : Application(), ImageLoaderFactory {
@ -71,6 +72,8 @@ class LinphoneApplication : Application(), ImageLoaderFactory {
Factory.instance().loggingService.setLogLevel(LogLevel.Message)
}
Log.i("[Linphone Application] Report Core preferences initialized")
coreContext = CoreContext(context)
coreContext.start()

View file

@ -251,6 +251,7 @@ class CoreContext @UiThread constructor(val context: Context) : HandlerThread("C
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
audioManager.registerAudioDeviceCallback(audioDeviceCallback, coreThread)
Log.i("$TAG Report Core created and started")
Looper.loop()
}

View file

@ -119,6 +119,10 @@ abstract class AbstractNewTransferCallFragment : GenericCallFragment() {
val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter)
binding.contactsAndSuggestionsList.addItemDecoration(headerItemDecoration)
if (binding.contactsAndSuggestionsList.adapter != adapter) {
binding.contactsAndSuggestionsList.adapter = adapter
}
adapter.contactClickedEvent.observe(viewLifecycleOwner) {
it.consume { model ->
startCall(model)
@ -134,10 +138,6 @@ abstract class AbstractNewTransferCallFragment : GenericCallFragment() {
val count = adapter.itemCount
adapter.submitList(it)
if (binding.contactsAndSuggestionsList.adapter != adapter) {
binding.contactsAndSuggestionsList.adapter = adapter
}
if (count == 0) {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()

View file

@ -73,6 +73,10 @@ class CallsListFragment : GenericCallFragment() {
binding.callsList.setHasFixedSize(true)
binding.callsList.layoutManager = LinearLayoutManager(requireContext())
if (binding.callsList.adapter != adapter) {
binding.callsList.adapter = adapter
}
adapter.callLongClickedEvent.observe(viewLifecycleOwner) {
it.consume { model ->
val modalBottomSheet = CallMenuDialogFragment(model) {
@ -97,10 +101,6 @@ class CallsListFragment : GenericCallFragment() {
viewModel.calls.observe(viewLifecycleOwner) {
Log.i("$TAG Calls list updated with [${it.size}] items")
adapter.submitList(it)
if (binding.callsList.adapter != adapter) {
binding.callsList.adapter = adapter
}
}
}

View file

@ -70,6 +70,10 @@ class ConferenceParticipantsListFragment : GenericCallFragment() {
binding.participantsList.setHasFixedSize(true)
binding.participantsList.layoutManager = LinearLayoutManager(requireContext())
if (binding.participantsList.adapter != adapter) {
binding.participantsList.adapter = adapter
}
binding.setBackClickListener {
findNavController().popBackStack()
}
@ -77,10 +81,6 @@ class ConferenceParticipantsListFragment : GenericCallFragment() {
viewModel.conferenceModel.participants.observe(viewLifecycleOwner) {
Log.i("$TAG participants list updated with [${it.size}] items")
adapter.submitList(it)
if (binding.participantsList.adapter != adapter) {
binding.participantsList.adapter = adapter
}
}
}
}

View file

@ -389,28 +389,19 @@ class MainActivity : GenericActivity() {
Log.i(
"$TAG Nav graph not set yet, loading it & set start destination to Conversations fragment instead of default"
)
val navGraph = findNavController().navInflater.inflate(
R.navigation.main_nav_graph
)
navGraph.setStartDestination(R.id.conversationsListFragment)
findNavController().setGraph(navGraph, intent.extras)
findNavController().navigate(R.id.conversationsListFragment)
}
} else {
Log.i(
"$TAG Loading graph & set start destination to Conversations fragment instead of default"
)
val navGraph = findNavController().navInflater.inflate(R.navigation.main_nav_graph)
navGraph.setStartDestination(R.id.conversationsListFragment)
findNavController().setGraph(navGraph, intent.extras)
findNavController().navigate(R.id.conversationsListFragment)
}
} else {
if (!isNewIntent && defaultDestination > 0) {
try {
Log.i("$TAG Setting nav graph with expected start destination")
val navGraph =
findNavController().navInflater.inflate(R.navigation.main_nav_graph)
navGraph.setStartDestination(defaultDestination)
findNavController().setGraph(navGraph, null)
findNavController().navigate(defaultDestination)
} catch (ise: IllegalStateException) {
Log.i("$TAG Failed to handle intent: $ise")
}
@ -499,10 +490,7 @@ class MainActivity : GenericActivity() {
intent.putExtra("LocalSipUri", localSipUri)
intent.putExtra("RemoteSipUri", remoteSipUri)
}
val navGraph = findNavController().navInflater.inflate(R.navigation.main_nav_graph)
navGraph.setStartDestination(R.id.conversationsListFragment)
findNavController().setGraph(navGraph, intent.extras)
findNavController().navigate(R.id.conversationsListFragment)
}
}
}

View file

@ -288,6 +288,10 @@ class ConversationFragment : SlidingPaneChildFragment() {
layoutManager.stackFromEnd = true
binding.eventsList.layoutManager = layoutManager
if (binding.eventsList.adapter != adapter) {
binding.eventsList.adapter = adapter
}
val callbacks = RecyclerViewSwipeUtilsCallback(
R.drawable.reply,
ConversationEventAdapter.EventViewHolder::class.java
@ -348,10 +352,6 @@ class ConversationFragment : SlidingPaneChildFragment() {
adapter.submitList(items)
Log.i("$TAG Events (messages) list updated with [${items.size}] items")
if (binding.eventsList.adapter != adapter) {
binding.eventsList.adapter = adapter
}
(view.parent as? ViewGroup)?.doOnPreDraw {
sharedViewModel.openSlidingPaneEvent.value = Event(true)
}

View file

@ -98,6 +98,10 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
binding.participants.setHasFixedSize(true)
binding.participants.layoutManager = LinearLayoutManager(requireContext())
if (binding.participants.adapter != adapter) {
binding.participants.adapter = adapter
}
viewModel.chatRoomFoundEvent.observe(viewLifecycleOwner) {
it.consume { found ->
if (found) {
@ -120,10 +124,6 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
viewModel.participants.observe(viewLifecycleOwner) { items ->
adapter.submitList(items)
Log.i("$TAG Participants list updated with [${items.size}] items")
if (binding.participants.adapter != adapter) {
binding.participants.adapter = adapter
}
}
viewModel.groupLeftEvent.observe(viewLifecycleOwner) {

View file

@ -126,6 +126,10 @@ class ConversationsListFragment : AbstractTopBarFragment() {
binding.conversationsList.setHasFixedSize(true)
binding.conversationsList.layoutManager = LinearLayoutManager(requireContext())
if (binding.conversationsList.adapter != adapter) {
binding.conversationsList.adapter = adapter
}
adapter.conversationLongClickedEvent.observe(viewLifecycleOwner) {
it.consume { model ->
val modalBottomSheet = ConversationDialogFragment(
@ -182,18 +186,9 @@ class ConversationsListFragment : AbstractTopBarFragment() {
}
listViewModel.conversations.observe(viewLifecycleOwner) {
val currentCount = adapter.itemCount
adapter.submitList(it)
Log.i("$TAG Conversations list ready with [${it.size}] items")
if (binding.conversationsList.adapter != adapter) {
binding.conversationsList.adapter = adapter
}
if (currentCount < it.size) {
binding.conversationsList.scrollToPosition(0)
}
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.isFirstFragmentReady = true

View file

@ -116,22 +116,19 @@ class ContactsListFragment : AbstractTopBarFragment() {
configureAdapter(adapter)
configureAdapter(favouritesAdapter)
if (binding.contactsList.adapter != adapter) {
binding.contactsList.adapter = adapter
}
if (binding.favouritesContactsList.adapter != favouritesAdapter) {
binding.favouritesContactsList.adapter = favouritesAdapter
}
listViewModel.contactsList.observe(
viewLifecycleOwner
) {
val currentCount = adapter.itemCount
adapter.submitList(it)
Log.i("$TAG Contacts list updated with [${it.size}] items")
if (binding.contactsList.adapter != adapter) {
binding.contactsList.adapter = adapter
}
if (currentCount < it.size) {
Log.i("$TAG Contacts list updated with new items, scrolling to top")
binding.contactsList.smoothScrollToPosition(0)
}
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.isFirstFragmentReady = true
@ -142,10 +139,6 @@ class ContactsListFragment : AbstractTopBarFragment() {
viewLifecycleOwner
) {
favouritesAdapter.submitList(it)
if (binding.favouritesContactsList.adapter != favouritesAdapter) {
binding.favouritesContactsList.adapter = favouritesAdapter
}
Log.i("$TAG Favourites contacts list updated with [${it.size}] items")
}

View file

@ -102,6 +102,10 @@ class HistoryContactFragment : SlidingPaneChildFragment() {
binding.callHistory.setHasFixedSize(true)
binding.callHistory.layoutManager = LinearLayoutManager(requireContext())
if (binding.callHistory.adapter != adapter) {
binding.callHistory.adapter = adapter
}
viewModel.callLogFoundEvent.observe(viewLifecycleOwner) {
it.consume { found ->
if (found) {
@ -128,10 +132,6 @@ class HistoryContactFragment : SlidingPaneChildFragment() {
viewModel.historyCallLogs.observe(viewLifecycleOwner) {
Log.i("$TAG Call history list ready with [${it.size}] items")
adapter.submitList(it)
if (binding.callHistory.adapter != adapter) {
binding.callHistory.adapter = adapter
}
}
viewModel.historyDeletedEvent.observe(viewLifecycleOwner) {

View file

@ -109,6 +109,10 @@ class HistoryListFragment : AbstractTopBarFragment() {
binding.historyList.setHasFixedSize(true)
binding.historyList.layoutManager = LinearLayoutManager(requireContext())
if (binding.historyList.adapter != adapter) {
binding.historyList.adapter = adapter
}
adapter.callLogLongClickedEvent.observe(viewLifecycleOwner) {
it.consume { model ->
val modalBottomSheet = HistoryMenuDialogFragment(
@ -188,18 +192,9 @@ class HistoryListFragment : AbstractTopBarFragment() {
}
listViewModel.callLogs.observe(viewLifecycleOwner) {
val currentCount = adapter.itemCount
adapter.submitList(it)
Log.i("$TAG Call logs ready with [${it.size}] items")
if (binding.historyList.adapter != adapter) {
binding.historyList.adapter = adapter
}
if (currentCount < it.size) {
binding.historyList.scrollToPosition(0)
}
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.isFirstFragmentReady = true

View file

@ -104,6 +104,10 @@ class MeetingsListFragment : AbstractTopBarFragment() {
val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter)
binding.meetingsList.addItemDecoration(headerItemDecoration)
if (binding.meetingsList.adapter != adapter) {
binding.meetingsList.adapter = adapter
}
binding.setNewMeetingClicked {
if (findNavController().currentDestination?.id == R.id.meetingsListFragment) {
Log.i("$TAG Navigating to schedule meeting fragment")
@ -131,10 +135,6 @@ class MeetingsListFragment : AbstractTopBarFragment() {
adapter.submitList(it)
Log.i("$TAG Meetings list ready with [$newCount] items")
if (binding.meetingsList.adapter != adapter) {
binding.meetingsList.adapter = adapter
}
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.isFirstFragmentReady = true

View file

@ -39,6 +39,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:navGraph="@navigation/main_nav_graph"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/in_call_top_bar"

View file

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_nav_graph"
app:startDestination="@id/historyListFragment">
app:startDestination="@id/contactsListFragment">
<fragment
android:id="@+id/contactsListFragment"