From 92a86094919970af22d0fe3e843398f32fa70687 Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Sat, 7 Jan 2017 19:34:42 +0800 Subject: [PATCH] refactored base fragments and activities fixed some memory leaks --- .../twidere/fragment/GoogleMapFragment.kt | 4 ++-- .../twidere/activity/BaseActivity.kt | 4 ++-- .../twidere/activity/HomeActivity.kt | 7 ++++-- .../twidere/activity/LinkHandlerActivity.kt | 2 +- .../twidere/activity/MediaViewerActivity.kt | 11 ++++----- .../activity/iface/IExtendedActivity.kt | 13 ++++++----- .../fragment/AbsToolbarTabPagesFragment.kt | 2 +- .../fragment/BasePreferenceFragment.kt | 4 ++-- .../twidere/fragment/BaseSupportFragment.kt | 4 ++-- .../twidere/fragment/DraftsFragment.kt | 6 ++--- .../twidere/fragment/UserFragment.kt | 23 +++++++++++-------- .../twidere/fragment/iface/IBaseFragment.kt | 21 +++++++---------- .../twidere/task/ProgressSaveFileTask.kt | 9 ++++---- 13 files changed, 54 insertions(+), 56 deletions(-) diff --git a/twidere/src/google/kotlin/org/mariotaku/twidere/fragment/GoogleMapFragment.kt b/twidere/src/google/kotlin/org/mariotaku/twidere/fragment/GoogleMapFragment.kt index 3026c30c7..0665d6780 100644 --- a/twidere/src/google/kotlin/org/mariotaku/twidere/fragment/GoogleMapFragment.kt +++ b/twidere/src/google/kotlin/org/mariotaku/twidere/fragment/GoogleMapFragment.kt @@ -37,7 +37,7 @@ import org.mariotaku.twidere.constant.IntentConstants.EXTRA_LONGITUDE import org.mariotaku.twidere.fragment.iface.IBaseFragment import org.mariotaku.twidere.fragment.iface.IMapFragment -class GoogleMapFragment : SupportMapFragment(), Constants, IMapFragment, IBaseFragment { +class GoogleMapFragment : SupportMapFragment(), Constants, IMapFragment, IBaseFragment { private val actionHelper = IBaseFragment.ActionHelper(this) @@ -108,7 +108,7 @@ class GoogleMapFragment : SupportMapFragment(), Constants, IMapFragment, IBaseFr } } - override fun executeAfterFragmentResumed(useHandler: Boolean, action: (IBaseFragment) -> Unit) { + override fun executeAfterFragmentResumed(useHandler: Boolean, action: (GoogleMapFragment) -> Unit) { actionHelper.executeAfterFragmentResumed(useHandler, action) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/BaseActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/BaseActivity.kt index 0934d6b08..d6713d006 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/BaseActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/BaseActivity.kt @@ -68,7 +68,7 @@ import java.util.* import javax.inject.Inject @SuppressLint("Registered") -open class BaseActivity : ChameleonActivity(), IExtendedActivity, IThemedActivity, +open class BaseActivity : ChameleonActivity(), IExtendedActivity, IThemedActivity, IControlBarActivity, OnFitSystemWindowsListener, SystemWindowsInsetsCallback, KeyboardShortcutCallback, OnPreferenceDisplayDialogCallback { @@ -273,7 +273,7 @@ open class BaseActivity : ChameleonActivity(), IExtendedActivity, IThemedActivit actionHelper.dispatchOnResumeFragments() } - override fun executeAfterFragmentResumed(action: (IExtendedActivity) -> Unit) { + override fun executeAfterFragmentResumed(action: (BaseActivity) -> Unit) { actionHelper.executeAfterFragmentResumed(action) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt index 48c7aa1cd..a08f4e605 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt @@ -765,8 +765,11 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp } private fun showAutoRefreshConfirm() { - val df = AutoRefreshConfirmDialogFragment() - df.show(supportFragmentManager, "auto_refresh_confirm") + if (isFinishing) return + executeAfterFragmentResumed { activity -> + val df = AutoRefreshConfirmDialogFragment() + df.show(activity.supportFragmentManager, "auto_refresh_confirm") + } } private fun setTabPosition(initialTab: Int) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/LinkHandlerActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/LinkHandlerActivity.kt index ccc97c5de..364f121d2 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/LinkHandlerActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/LinkHandlerActivity.kt @@ -85,7 +85,7 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro override fun onFitSystemWindows(insets: Rect) { super.onFitSystemWindows(insets) val fragment = currentVisibleFragment - if (fragment is IBaseFragment) { + if (fragment is IBaseFragment<*>) { fragment.requestFitSystemWindows() } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/MediaViewerActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/MediaViewerActivity.kt index 2d28385e1..5f6b5f089 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/MediaViewerActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/MediaViewerActivity.kt @@ -25,7 +25,6 @@ import android.os.Bundle import android.os.Parcelable import android.support.v4.app.DialogFragment import android.support.v4.app.Fragment -import android.support.v4.app.FragmentActivity import android.support.v4.app.hasRunningLoadersSafe import android.support.v4.content.ContextCompat import android.support.v4.view.ViewPager @@ -57,7 +56,7 @@ import java.io.File import javax.inject.Inject import android.Manifest.permission as AndroidPermissions -class MediaViewerActivity : BaseActivity(), IExtendedActivity, IMediaViewerActivity { +class MediaViewerActivity : BaseActivity(), IMediaViewerActivity { @Inject lateinit var mFileCache: FileCache @@ -342,20 +341,20 @@ class MediaViewerActivity : BaseActivity(), IExtendedActivity, IMediaViewerActiv private val PROGRESS_FRAGMENT_TAG = "progress" override fun dismissProgress() { - val activity = context as IExtendedActivity + val activity = context as IExtendedActivity<*> activity.executeAfterFragmentResumed { activity -> - val fm = (activity as FragmentActivity).supportFragmentManager + val fm = activity.supportFragmentManager val fragment = fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG) as? DialogFragment fragment?.dismiss() } } override fun showProgress() { - val activity = context as IExtendedActivity + val activity = context as IExtendedActivity<*> activity.executeAfterFragmentResumed { activity -> val fragment = ProgressDialogFragment() fragment.isCancelable = false - fragment.show((activity as FragmentActivity).supportFragmentManager, PROGRESS_FRAGMENT_TAG) + fragment.show(activity.supportFragmentManager, PROGRESS_FRAGMENT_TAG) } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/iface/IExtendedActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/iface/IExtendedActivity.kt index 68679b83e..2b3ac094b 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/iface/IExtendedActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/iface/IExtendedActivity.kt @@ -19,19 +19,20 @@ package org.mariotaku.twidere.activity.iface +import android.support.v4.app.FragmentActivity import java.util.* /** * Created by mariotaku on 15/12/28. */ -interface IExtendedActivity { +interface IExtendedActivity { - fun executeAfterFragmentResumed(action: (IExtendedActivity) -> Unit) + fun executeAfterFragmentResumed(action: (A) -> Unit) - class ActionHelper(private val activity: IExtendedActivity) { + class ActionHelper(private val activity: A) { private var fragmentResumed: Boolean = false - private val actionQueue = LinkedList<(IExtendedActivity) -> Unit>() + private val actionQueue = LinkedList<(A) -> Unit>() fun dispatchOnPause() { fragmentResumed = false @@ -45,14 +46,14 @@ interface IExtendedActivity { private fun executePending() { if (!fragmentResumed) return - var action: ((IExtendedActivity) -> Unit)? + var action: ((A) -> Unit)? do { action = actionQueue.poll() action?.invoke(activity) } while (action != null) } - fun executeAfterFragmentResumed(action: (IExtendedActivity) -> Unit) { + fun executeAfterFragmentResumed(action: (A) -> Unit) { actionQueue.add(action) executePending() } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsToolbarTabPagesFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsToolbarTabPagesFragment.kt index 26ec98926..0457548a6 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsToolbarTabPagesFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsToolbarTabPagesFragment.kt @@ -61,7 +61,7 @@ abstract class AbsToolbarTabPagesFragment : BaseSupportFragment(), RefreshScroll for (i in 0 until count) { if (i > currentItem - pageLimit - 1 || i < currentItem + pageLimit) { val obj = pagerAdapter!!.instantiateItem(viewPager, i) - if (obj is IBaseFragment) { + if (obj is IBaseFragment<*>) { obj.requestFitSystemWindows() } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BasePreferenceFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BasePreferenceFragment.kt index c7e69c59f..aaa78caff 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BasePreferenceFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BasePreferenceFragment.kt @@ -39,7 +39,7 @@ import org.mariotaku.twidere.util.dagger.GeneralComponentHelper import org.mariotaku.twidere.util.sync.SyncController import javax.inject.Inject -abstract class BasePreferenceFragment : PreferenceFragmentCompat(), IBaseFragment { +abstract class BasePreferenceFragment : PreferenceFragmentCompat(), IBaseFragment { private var ringtonePreferenceKey: String? = null @Inject @@ -122,7 +122,7 @@ abstract class BasePreferenceFragment : PreferenceFragmentCompat(), IBaseFragmen return super.onPreferenceTreeClick(preference) } - override fun executeAfterFragmentResumed(useHandler: Boolean, action: (IBaseFragment) -> Unit) { + override fun executeAfterFragmentResumed(useHandler: Boolean, action: (BasePreferenceFragment) -> Unit) { actionHelper.executeAfterFragmentResumed(useHandler, action) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseSupportFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseSupportFragment.kt index 11cdd6808..a43ddc423 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseSupportFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseSupportFragment.kt @@ -29,7 +29,7 @@ import org.mariotaku.twidere.util.* import org.mariotaku.twidere.util.dagger.GeneralComponentHelper import javax.inject.Inject -open class BaseSupportFragment : Fragment(), IBaseFragment { +open class BaseSupportFragment : Fragment(), IBaseFragment { // Utility classes @Inject @@ -69,7 +69,7 @@ open class BaseSupportFragment : Fragment(), IBaseFragment { GeneralComponentHelper.build(context!!).inject(this) } - override fun executeAfterFragmentResumed(useHandler: Boolean, action: (IBaseFragment) -> Unit) { + override fun executeAfterFragmentResumed(useHandler: Boolean, action: (BaseSupportFragment) -> Unit) { actionHelper.executeAfterFragmentResumed(useHandler, action) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/DraftsFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/DraftsFragment.kt index 25b159230..2d24bfb43 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/DraftsFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/DraftsFragment.kt @@ -300,8 +300,7 @@ class DraftsFragment : BaseSupportFragment(), LoaderCallbacks, OnItemCl override fun onPreExecute() { super.onPreExecute() - (activity as IExtendedActivity).executeAfterFragmentResumed { - val activity = it as FragmentActivity + (activity as IExtendedActivity<*>).executeAfterFragmentResumed { activity -> val f = ProgressDialogFragment.show(activity.supportFragmentManager, FRAGMENT_TAG_DELETING_DRAFTS) f.isCancelable = false } @@ -309,8 +308,7 @@ class DraftsFragment : BaseSupportFragment(), LoaderCallbacks, OnItemCl override fun onPostExecute(result: Unit) { super.onPostExecute(result) - (activity as IExtendedActivity).executeAfterFragmentResumed { - val activity = it as FragmentActivity + (activity as IExtendedActivity<*>).executeAfterFragmentResumed { activity -> val fm = activity.supportFragmentManager val f = fm.findFragmentByTag(FRAGMENT_TAG_DELETING_DRAFTS) if (f is DialogFragment) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserFragment.kt index 00cec2092..fc29d79ae 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserFragment.kt @@ -130,6 +130,7 @@ import org.mariotaku.twidere.util.support.WindowSupport import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback import org.mariotaku.twidere.view.TabPagerIndicator import org.mariotaku.twidere.view.iface.IExtendedView.OnSizeChangedListener +import java.lang.ref.WeakReference import java.util.* class UserFragment : BaseSupportFragment(), OnClickListener, OnLinkClickListener, @@ -931,14 +932,14 @@ class UserFragment : BaseSupportFragment(), OnClickListener, OnLinkClickListener df?.dismiss() } }.successUi { result -> - executeAfterFragmentResumed { + executeAfterFragmentResumed { fragment -> val df = AddRemoveUserListDialogFragment() df.arguments = Bundle { this[EXTRA_ACCOUNT_KEY] = user.account_key this[EXTRA_USER_KEY] = user.key this[EXTRA_USER_LISTS] = result } - df.show(fragmentManager, "add_remove_list") + df.show(fragment.fragmentManager, "add_remove_list") } }.failUi { Utils.showErrorMessage(context, R.string.action_getting_user_lists, it, false) @@ -1594,14 +1595,15 @@ class UserFragment : BaseSupportFragment(), OnClickListener, OnLinkClickListener dialog.setOnShowListener { dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener { val checkedPositions = dialog.listView.checkedItemPositions - + val weakActivity = WeakReference(activity) promiseOnUi { - val activity = activity as IExtendedActivity - activity.executeAfterFragmentResumed { - ProgressDialogFragment.show(fragmentManager, "update_lists_progress") + val activity = weakActivity.get() as? IExtendedActivity<*> ?: return@promiseOnUi + activity.executeAfterFragmentResumed { activity -> + ProgressDialogFragment.show(activity.supportFragmentManager, "update_lists_progress") } }.then { - val twitter = MicroBlogAPIFactory.getInstance(context, accountKey) + val activity = weakActivity.get() ?: throw IllegalStateException() + val twitter = MicroBlogAPIFactory.getInstance(activity, accountKey) val successfulStates = SparseBooleanArray() try { for (i in 0 until checkedPositions.size()) { @@ -1620,9 +1622,10 @@ class UserFragment : BaseSupportFragment(), OnClickListener, OnLinkClickListener throw UpdateListsException(successfulStates) } }.alwaysUi { - val activity = activity as IExtendedActivity - activity.executeAfterFragmentResumed { - val df = fragmentManager.findFragmentByTag("update_lists_progress") as? DialogFragment + val activity = weakActivity.get() as? IExtendedActivity<*> ?: return@alwaysUi + activity.executeAfterFragmentResumed { activity -> + val manager = activity.supportFragmentManager + val df = manager.findFragmentByTag("update_lists_progress") as? DialogFragment df?.dismiss() } }.successUi { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/iface/IBaseFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/iface/IBaseFragment.kt index df33b223e..930d6027f 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/iface/IBaseFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/iface/IBaseFragment.kt @@ -27,7 +27,7 @@ import android.support.v4.app.Fragment import org.mariotaku.twidere.constant.IntentConstants import java.util.* -interface IBaseFragment { +interface IBaseFragment { val extraConfiguration: Bundle? get() = null @@ -64,18 +64,14 @@ interface IBaseFragment { fun getSystemWindowsInsets(insets: Rect): Boolean } - fun executeAfterFragmentResumed(useHandler: Boolean = false, action: (IBaseFragment) -> Unit) + fun executeAfterFragmentResumed(useHandler: Boolean = false, action: (F) -> Unit) - class ActionHelper(private val fragment: IBaseFragment) { + class ActionHelper(private val fragment: F) { - private val handler: Handler - - init { - handler = Handler(Looper.getMainLooper()) - } + private val handler: Handler = Handler(Looper.getMainLooper()) private var fragmentResumed: Boolean = false - private val actionQueue = LinkedList() + private val actionQueue = LinkedList>() fun dispatchOnPause() { fragmentResumed = false @@ -86,10 +82,9 @@ interface IBaseFragment { executePending() } - private fun executePending() { if (!fragmentResumed) return - var info: ExecuteInfo + var info: ExecuteInfo while (true) { info = actionQueue.poll() ?: break if (info.useHandler) { @@ -100,11 +95,11 @@ interface IBaseFragment { } } - fun executeAfterFragmentResumed(useHandler: Boolean = false, action: (IBaseFragment) -> Unit) { + fun executeAfterFragmentResumed(useHandler: Boolean = false, action: (F) -> Unit) { actionQueue.add(ExecuteInfo(action, useHandler)) executePending() } - private data class ExecuteInfo(val action: (IBaseFragment) -> Unit, val useHandler: Boolean) + private data class ExecuteInfo(val action: (F) -> Unit, val useHandler: Boolean) } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/ProgressSaveFileTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/ProgressSaveFileTask.kt index 37dcecada..5bb075cf0 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/ProgressSaveFileTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/ProgressSaveFileTask.kt @@ -22,7 +22,6 @@ package org.mariotaku.twidere.task import android.content.Context import android.net.Uri import android.support.v4.app.DialogFragment -import android.support.v4.app.FragmentActivity import org.mariotaku.twidere.activity.iface.IExtendedActivity import org.mariotaku.twidere.fragment.ProgressDialogFragment import java.io.File @@ -38,16 +37,16 @@ abstract class ProgressSaveFileTask( ) : SaveFileTask(context, source, destination, getMimeType) { override fun showProgress() { - (context as IExtendedActivity).executeAfterFragmentResumed { activity -> + (context as IExtendedActivity<*>).executeAfterFragmentResumed { activity -> val fragment = ProgressDialogFragment() fragment.isCancelable = false - fragment.show((activity as FragmentActivity).supportFragmentManager, PROGRESS_FRAGMENT_TAG) + fragment.show(activity.supportFragmentManager, PROGRESS_FRAGMENT_TAG) } } override fun dismissProgress() { - (context as IExtendedActivity).executeAfterFragmentResumed { activity -> - val fm = (activity as FragmentActivity).supportFragmentManager + (context as IExtendedActivity<*>).executeAfterFragmentResumed { activity -> + val fm = activity.supportFragmentManager val fragment = fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG) as? DialogFragment fragment?.dismiss() }