活动com.empowered.healo.ui.activities.main.MainActivity泄漏了最初在此处添加的窗口DecorView @ adb6956 [MainActivity]

时间:2018-12-28 09:58:49

标签: android kotlin dialog

我正在开发一个新应用,但是当用户使用电子邮件和密码登录时崩溃

来自Logcat的错误

android.view.WindowLeaked: Activity com.empowered.healo.ui.activities.main.MainActivity has leaked window DecorView@adb6956[MainActivity] that was originally added here
        at android.view.ViewRootImpl.<init>(ViewRootImpl.java:572)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:97)
        at android.app.Dialog.show(Dialog.java:419)
        at com.empowered.healo.mvp.BaseMvpActivity.showError(BaseMvpActivity.java:70)
        at com.empowered.healo.ui.activities.main.MainPresenter$getHelpTexts$2.accept(MainPresenter.kt:132)
        at com.empowered.healo.ui.activities.main.MainPresenter$getHelpTexts$2.accept(MainPresenter.kt:25)
        at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:74)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.checkTerminated(ObservableObserveOn.java:276)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:172)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252)
        at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6682)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

在我的MainActivity.kt下面

     class MainActivity : BaseMvpActivity(), MainView {
         companion object {
             const val ACTION_FRAGMENT = "FRAGMENT_CHANGE"
             const val DELETE_THERAPY = "DELETE_THERAPY"
             const val CHANGE_PROFILE = "CHANGE_PROFILE"
             const val UPDATE_DATA = "UPDATE_DATA"
         }

         private var presenter = MainPresenter(this)
         private var navigator: Navigator? = null
         private var needUpdateData: Boolean = false
         private var pushData: Bundle = Bundle()
         private var needRedirect: Boolean = false
         private var fragmentReceiver: BroadcastReceiver? = null
         private var actionDrawerClose: (() - Unit)? = null
         private var firstScreen: String = Screen.HOME

         override fun onCreate(savedInstanceState: Bundle?) {
             super.onCreate(savedInstanceState)
             setContentView(R.layout.activity_main)
             handleInComeIntent()
             initNavigation()
             initData()
             initUI()
         }

         private fun initData() {
             presenter.subscribeToNotification()
             if (needUpdateData)
                 presenter.getSession(firstScreen)
             else moveToScreen(firstScreen, null)
             presenter.getHelpTexts()
         }

         private fun initNavigation() {
             navigator = getNavigator()
             (application as HealApplication).setNavigator(navigator)
         }

         private fun initUI() {
             Glide.with(this)
                     .load(R.drawable.splash)
                     .into(backgroundImage)

             initNavDrawer()
             val keyboardUtil = KeyboardUtil(this, drawerLayout.getChildAt(1))
             keyboardUtil.enable()
         }

         override fun onNewIntent(intent: Intent?) {
             super.onNewIntent(intent)
             this.intent = intent
             handleInComeIntent()
             if (needRedirect) {
                 needRedirect = false
                 (application as HealApplication).router.navigateTo(firstScreen, pushData)
             }
         }

         override fun onStart() {
             super.onStart()
             fragmentReceiver = object : BroadcastReceiver() {
                 override fun onReceive(context: Context?, intent: Intent?) {
                     when (intent?.action) {
                         ACTION_FRAGMENT - {
                             changeBackground()
                         }

                         DELETE_THERAPY - {
                             checkMenuState()
                         }

                         CHANGE_PROFILE - {
                             updateIcons()
                             navList.updateMenuItems()
                         }
                     }

                 }
             }
             val intentFilter = IntentFilter(ACTION_FRAGMENT)
             intentFilter.addAction(DELETE_THERAPY)
             intentFilter.addAction(CHANGE_PROFILE)
             fragmentReceiver?.let { LocalBroadcastManager.getInstance(this).registerReceiver(it,
 intentFilter) }

         }

         fun changeBackground() {
             val fragment = supportFragmentManager.findFragmentById(R.id.fragmentContainer)
             if (fragment != null && fragment is BaseMvpFragment && fragment.rootView != null) {
                 fragment.rootView.isDrawingCacheEnabled = true
                 (fragment as? HomeFragment)?.take()
                 fragment.rootView.buildDrawingCache(true)
                 val cache = fragment.rootView.getDrawingCache(true)
                 cache?.let {
                     if (backgroundImage.scaleType == ImageView.ScaleType.FIT_XY) {
                         backgroundImage.scaleType = ImageView.ScaleType.FIT_CENTER
                     }
                     backgroundImage.setImageDrawable(null)
                     val bitmap = Bitmap.createBitmap(cache)
                     backgroundImage.setImageBitmap(bitmap)
                 }
                 fragment.rootView.isDrawingCacheEnabled = false
             }
         }

         private fun updateIcons() {
             presenter.getGender()?.let {
                 when (it) {
                     User.Gender.MALE - navList.updateIconForMenuItem(R.string.item_menu_pain_profile,
 R.drawable.ic_icon_menu_pain_profile_man)
                     User.Gender.FEMALE - navList.updateIconForMenuItem(R.string.item_menu_pain_profile,
 R.drawable.ic_menu_pain_profile_woman)
                 }
             }

         }

         private fun checkMenuState() {
             navList.updateState(if (presenter.isFullMenu()) MenuView.MenuState.FULL else MenuView.MenuState.SHORT)
         }

         override fun onStop() {
             super.onStop()
             fragmentReceiver?.let { LocalBroadcastManager.getInstance(this).unregisterReceiver(it) }
         }

         private fun handleInComeIntent() {
             needRedirect = false
             intent?.let { intent -
                 needUpdateData = intent.getBooleanExtra(UPDATE_DATA, true)
                 //Local reminder
                 when (intent.getStringExtra(Notifications.PushData.ACTION)) {
                     Notifications.PushData.Reminder.OPEN_SESSION - {
                         pushData.putAll(intent.extras)
                         firstScreen = Screen.START_SESSION
                         needRedirect = true
                     }
                 }
                 //From server push notification
                 when (intent.getStringExtra(Notifications.PushData.HEAL_EVENT)?.substringAfterLast("\\"))
 {
                     Notifications.PushData.Message.MESSAGE_EVENT - {
                         firstScreen = Screen.CHAT
                         needRedirect = true
                     }
                     Notifications.PushData.Evaluation.EVALUATION_EVENT - {
                         pushData.putInt(Notifications.PushData.Evaluation.EVALUATION_ID,
 intent.getStringExtra(Notifications.PushData.Evaluation.EVALUATION_ID).toInt())
                         pushData.putString(Notifications.PushData.ACTION,
 Notifications.PushData.Evaluation.EVALUATION)
                         firstScreen = Screen.START_SESSION
                         needRedirect = true
                     }
                 }
                 intent?.extras?.clear()
                 val closeIntent = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
                 sendBroadcast(closeIntent)
                 toggleDrawerScreen(false)

             }
         }

         override fun handleNewDialogMessage() {
             val currentFragment = supportFragmentManager.findFragmentById(R.id.fragmentContainer)
             if (currentFragment !is ChatFragment) {
                 val badgeCount = navList.updateBadgeForMenuItem(R.string.support_feedback, 1)
                 Notifications.sendNotification(this,
                         Notifications.MessageNotification(this, Notifications.PushData.Message.LOCAL_PUSH_ID,
 badgeCount).createNotification(),
                         Notifications.PushData.Message.LOCAL_PUSH_ID)
             }
         }

         override fun setChatBadgeCount(count: Int) {
             navList.clearBadgeForMenuItem(R.string.support_feedback)
             navList.updateBadgeForMenuItem(R.string.support_feedback, count)
         }

         override fun startEvaluation(evaluationId: Int) {
             EvaluationDialog(evaluationId, activity = this).build()?.show()
         }

         private fun initNavDrawer() {
             closeDrawer.setOnClickListener { toggleDrawerScreen(false) }
             drawerLayout?.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED,
 Gravity.END)
             drawerLayout?.addDrawerListener(object : DrawerLayout.DrawerListener {
                 override fun onDrawerStateChanged(newState: Int) {

                 }

                 override fun onDrawerSlide(drawerView: View, slideOffset: Float) {

                 }

                 override fun onDrawerClosed(drawerView: View) {
                     actionDrawerClose?.invoke()
                 }

                 override fun onDrawerOpened(drawerView: View) {
                     actionDrawerClose = null
                 }


             })


             /*

             navList.setOnItemClickListener(object : ItemClickListener<MenuView.MenuItem {
             override fun onItemClicked(t: MenuView.MenuItem, position: Int) {
                 val fragment = Fragment()
                 val data = Bundle()
                 when (position) {
                     0 - {
                         fragment = NameOfYourFragment()
                     }

                     1 - {
                         fragment = NameOfYourFragment()
                     }

                     2 - {
                         fragment = NameOfYourFragment()
                     }

                     3 - {
                         fragment = NameOfYourFragment()
                     }

                     4 - {
                         fragment = NameOfYourFragment()
                     }

                     5 - {
                         fragment = NameOfYourFragment()
                     }

                     6 - {
                         fragment = NameOfYourFragment()
                     }
                     7 - {
                         toggleDrawerScreen(false)
                         presenter.logOut()
                         return
                     }
                     8 - {
                         navList.clearBadgeForMenuItem(R.string.support_feedback)
                         Notifications.cancelNotification(this@MainActivity,
 Notifications.PushData.Message.LOCAL_PUSH_ID)
                         fragment = NameOfYourFragment()
                     }

                     9 - {
                         data.putBoolean("profile", true)
                         fragment = NameOfYourFragment()
                     }
                     10 - {
                         fragment = NameOfYourFragment()
                     }
                     11 - {
                         data.putBoolean(AboutFragment.BACKGROUND_VIDEO, true)
                         fragment = NameOfYourFragment()
                     }
                     12 - {
                         fragment = NameOfYourFragment()
                     }
                     13 - {
                         fragment = NameOfYourFragment()
                         data.putBoolean(WebPageFragment.DIALOG, false)
                         data.putString(WebPageFragment.TOOLBAR_TITLE, getString(t.title))
                         data.putString(WebPageFragment.URL, BuildConfig.PRIVACY_POLICY)
                     }

                     14 -
                         fragment = NameOfYourFragment()

                     16 - fragment = NameOfYourFragment()

                     else - toggleDrawerScreen(false)

                 }
                 toggleDrawerScreen(false)


             }
         })

              */




             navList.setOnItemClickListener(object : ItemClickListener<MenuView.MenuItem {
                 override fun onItemClicked(t: MenuView.MenuItem, position: Int) {
                     val fragment = supportFragmentManager.findFragmentById(R.id.fragmentContainer)
                     var screen = ""
                     @Suppress("Annotator", "Annotator", "Annotator", "Annotator", "Annotator", "Annotator", "Annotator", "Annotator",
 "Annotator") val currentScreen =
 fragment!!.arguments?.getString(ScreenNavigator.SCREEN_NAME)
                     val data = Bundle()
                     when (t.title) {
                         R.string.item_menu_home - {
                             screen = Screen.HOME

                         }
                         R.string.item_menu_session - {
                             screen = Screen.START_SESSION
                         }

                         R.string.item_menu_pain_profile - {
                             screen = Screen.SELF_DIAGNOSIS
                         }
     // it crashed? lets try again.
                         R.string.item_menu_favourite - {
                             screen = Screen.FAVOURITE_EXERCISES
                         }

                         R.string.item_menu_progress_prognosis - {
                             screen = Screen.PROGRESS
                         }

                         R.string.item_menu_schedule_reminders - {
                             screen = Screen.SCHEDULE
                         }

                         R.string.item_menu_therapy_settings - {
                             screen = Screen.THERAPY_SETTINGS
                         }
                         R.string.sign_out - {
                             toggleDrawerScreen(false)
                             presenter.logOut()
                             return
                         }
                         R.string.support_feedback - {
                             navList.clearBadgeForMenuItem(R.string.support_feedback)
                             Notifications.cancelNotification(this@MainActivity,
 Notifications.PushData.Message.LOCAL_PUSH_ID)
                             screen = Screen.CHAT
                         }

                         R.string.item_menu_account - {
                             data.putBoolean("profile", true)
                             screen = Screen.PROFILE
                         }
                         R.string.therapy_information - {
                             screen = Screen.THERAPY_INFO
                         }
                         R.string.about_healo - {
                             data.putBoolean(AboutFragment.BACKGROUND_VIDEO, true)
                             screen = Screen.ABOUT
                         }
                         R.string.activity_journal - {
                             screen = Screen.ACTIVITY_JOURNAL
                         }
                         R.string.privacy_policy_title - {
                             screen = Screen.WEB_PAGE
                             data.putBoolean(WebPageFragment.DIALOG, false)
                             data.putString(WebPageFragment.TOOLBAR_TITLE, getString(t.title))
                             data.putString(WebPageFragment.URL, BuildConfig.PRIVACY_POLICY)
                         }

                         R.string.payment_settings -
                             screen = Screen.PAYMENT_SETTINGS

                         R.string.subscriptions - screen = Screen.SUBSCRIPTIONS

                         else - toggleDrawerScreen(false)

                     }
                     toggleDrawerScreen(false)

                     if (!screen.isEmpty() && screen != currentScreen) {
                         actionDrawerClose = if ((fragment is OnBackPressed) && (fragment.onBackPressed(screen, data))) {
                             null
                         } else {
                             { HealApplication.INSTANCE.router.navigateTo(screen, data) }
                         }
                     } else {
                         actionDrawerClose = null
                     }
                 }
             })
             navList.addItemDecoration(object : RecyclerView.ItemDecoration() {
                 override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
                     super.getItemOffsets(outRect, view, parent, state)
                     val position = parent.getChildAdapterPosition(view)
                     if (position == 0) {
                         outRect.top = 9.5f.dp
                     }
                 }
             })
             updateIcons()

             navList.layoutParams.width = getScreenWidth() / 2
             drawerListContainer.layoutParams.width = getScreenWidth() / 2
             drawerListContainer.invalidate()
             navList.requestLayout()
         }

         fun toggleDrawerScreen(open: Boolean) {
             if (open) {
                 hideKeyboard()
                 setDrawerAnimation()
                 drawerLayout?.openDrawer(Gravity.END)
             } else {
                 drawerLayout?.closeDrawer(Gravity.END, true)
             }

         }

         private fun setDrawerAnimation() {
             val animatorRecycler = ObjectAnimator.ofFloat(navList, View.TRANSLATION_X, 250f, 0f)
             animatorRecycler.duration = 500
             animatorRecycler.interpolator = LinearInterpolator()
             animatorRecycler.start()
         }

         private fun getScreenWidth(): Int {
             val display = windowManager.defaultDisplay
             val size = Point()
             display.getSize(size)
             return Math.max(size.x, size.y)
         }

         override fun onBackPressed() {
             val fragment = supportFragmentManager.findFragmentById(R.id.fragmentContainer)

             if (fragment is OnBackPressed) {
                 if (fragment.onBackPressed(null, null))
                     super.onBackPressed()
             } else {
                 if (drawerLayout.isDrawerOpen(Gravity.END)) {
                     drawerLayout.closeDrawer(Gravity.END, true)
                 } else {
                     super.onBackPressed()
                 }
             }
         }


     override fun moveToScreen(screen: String, data: Bundle?) {
         val bundle = Bundle()
         if (data != null)
             bundle.putAll(data)
         bundle.putAll(pushData)
         checkMenuState()
         if (needRedirect) {
             (application as HealApplication).router.newRootScreen(Screen.HOME, null)
             (application as HealApplication).router.navigateTo(screen, bundle)

         } else {
             (application as HealApplication).router.newRootScreen(screen, bundle)
         }
     }

     override fun onDestroy() {
         super.onDestroy()
         presenter.disconnectFromNotification()
     }

     private fun hideKeyboard() {
         KeyboardUtil.hideKeyboard(this)
     }

     override fun startGuide() {
         startActivityForResult(Intent(this, GuidanceActivity::class.java), GuidanceActivity.REQUEST_CODE)
     }

     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
         super.onActivityResult(requestCode, resultCode, data)
         DiagnosticActivity.handleResult(data, requestCode, resultCode, (application as HealApplication).router)

         if (requestCode == GuidanceActivity.REQUEST_CODE) {
             moveToScreen(Screen.PROFILE, null)
         }
     }

     override fun onLogout() {
         finish()
         HealApplication.logout()
     }

     private fun getNavigator(): Navigator {
         return ScreenNavigator(this, R.id.fragmentContainer, Screen::class.java).navigator
     }

     override fun networkAvailable(isNetworkAvailable: Boolean) {

     }


 }

MainPresenter类

 class MainPresenter(var view: MainView) : BaseMvpPresenter() {

 private val exerciseRepository = SessionsRepository()
 private val reportDb = SessionReportDatabase()
 private val db = DiagnosticHistoryDatabase()
 private val dbTherapy = TherapyDatabaseV2()
 private val apiDiagnostic = DiagnosticNetwork()
 private val chatRepository = ChatRepository()
 private val usersNetwork = UsersNetwork()

 fun subscribeToNotification() {
     chatRepository.getUnreadMessageCount()
             .observeOn(AndroidSchedulers.mainThread())
             .subscribe({
                 view.setChatBadgeCount(it)
             }, Throwable::printStackTrace)

       val user = UsersDatabase.getCurrentUser()
      if (user == null)
         return

        SocketNetwork.instance.connect(SocketNetwork.instance.NOTIFICATION,user.id)
       val clazz = HashMap<String, Any()
       SocketNetwork.instance.addEvent(SocketNetwork.instance.NOTIFICATION +
  ":${user.id}", SocketNetwork.instance.NOTIFICATION, clazz.javaClass)
             .subscribeOn(Schedulers.io())
             .observeOn(AndroidSchedulers.mainThread())
             .subscribe({
                 Log.i("NOTIFICATION", it.toString())
                 when (it.getValue("event")) {
                     Notifications.PushData.Evaluation.EVALUATION_EVENT - {
                         val value = (it.getValue(Notifications.PushData.Evaluation.EVALUATION_ID) as
  Double).toInt()
                         view.startEvaluation(value)
                     }

                     Notifications.PushData.Message.MESSAGE_EVENT - {
                         view.handleNewDialogMessage()
                     }

                 }
             }, {
                 it.printStackTrace()
             })
 }

 fun disconnectFromNotification() {
     SocketNetwork.instance.closeSocket(SocketNetwork.instance.NOTIFICATION)
 }

 fun getSession(screen: String = Screen.HOME) {
     view.showLoading()
     exerciseRepository.getTherapyActive()
             .observeOn(AndroidSchedulers.mainThread())
             .subscribe({
                 view.hideLoading()
                 if (!it.isEmpty())
                     view.moveToScreen(screen, Bundle())
                 else checkLastDiagnostic()
             }, {
                 view.hideLoading()
                 it.printStackTrace()
                 view.moveToScreen(Screen.SELF_DIAGNOSIS, Bundle())
                 // logOut()
             })

     exerciseRepository.syncReports()
             .observeOn(AndroidSchedulers.mainThread())
             .flatMapIterable { it }
             .subscribe({
                 reportDb.updateSessionReport(it)
             }, Throwable::printStackTrace)


 }

 fun isFullMenu(): Boolean =
         dbTherapy.getAllTherapyCount()  0


 private fun checkLastDiagnostic() {
     view.showLoading()
     apiDiagnostic.getLastDiagnostic()
             .observeOn(AndroidSchedulers.mainThread())
             .switchIfEmpty {
                 view.hideLoading()
                 view.startGuide()
             }
             .subscribe({
                 view.hideLoading()
                 db.saveDiagnosticHistory(it)
                 val data = Bundle()
                 data.putBoolean("enable", false)
                 view.moveToScreen(Screen.SELF_DIAGNOSIS, data)
             }, {
                 view.hideLoading()
                 view.startGuide()
             })
 }

 fun logOut() {
     usersNetwork.logOut(UsersDatabase().getToken())
             .observeOn(AndroidSchedulers.mainThread())
             .subscribe({ view.onLogout() }, { view.showError(it.message) })
 }

 fun getHelpTexts() {
     usersNetwork.getHelpTexts(UsersDatabase().getToken())
             .observeOn(AndroidSchedulers.mainThread())
             .subscribe({ data - UsersDatabase().saveHelpText(data) }, { view.showError(it.message) })
 }

 fun getGender(): User.Gender? = UsersDatabase.getCurrentUser()?.getGender()

 }

1 个答案:

答案 0 :(得分:-1)

您可以尝试一下吗

在显示对话框之前,我添加了检查活动是否正在关闭的功能。除了消息,还要接受上下文并尝试。

@Override
    public void showError(Context context, String errorMessage) {
        if (errorMessage == null || errorMessage.trim().isEmpty())
            errorMessage = getString(R.string.default_error_message);
        AlertDialog dialog = new CustomAlertDialogBuilder(context)
                .addMessage(errorMessage)
                .setPositiveButton("OK", DialogInterface::dismiss)
                .build();
        try {
            if (dialog != null) {
                dialogs.add(dialog);

                //Added this line 

                if(!isFinishing()) 
                   dialog.show();
            }
        } catch (Exception e) {
            Crashlytics.logException(e);
        }
    }


@Override
    public void showError(Context context, int errorMessage) {
        showError(context, getString(errorMessage));
    }