Skip to content

Commit

Permalink
添加直播过滤
Browse files Browse the repository at this point in the history
  • Loading branch information
guwen committed May 20, 2020
1 parent f050322 commit e72cf61
Show file tree
Hide file tree
Showing 10 changed files with 277 additions and 4 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ buildscript {
robolectric: 'org.robolectric:robolectric:4.0-alpha-3',
]
repositories {
mavenCentral()
google()
maven { url 'https://plugins.gradle.org/m2/' }
maven { url "https://jitpack.io" }
jcenter()
}
dependencies {
Expand All @@ -53,6 +55,7 @@ buildscript {
classpath 'com.github.ben-manes:gradle-versions-plugin:0.20.0'
classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.18"
classpath deps.detekt
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
}
}

Expand Down
2 changes: 2 additions & 0 deletions leakcanary-android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'com.github.dcendents.android-maven'
group='com.github.CaiNiaoCYY'

dependencies {
api project(':leakcanary-android-core')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# AndroidXFragmentDestroyWatcher is loaded via reflection
-keep class leakcanary.internal.AndroidXFragmentDestroyWatcher { *; }
-keep class leakcanary.internal.LiveAndroidXFragmentDestroyWatcher { *; }
# ViewModelClearedWatcher reaches into ViewModelStore using reflection.
-keep class androidx.lifecycle.ViewModelStore { *; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (C) 2018 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package leakcanary.internal

import android.app.Activity
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import leakcanary.AppWatcher.Config
import leakcanary.ObjectWatcher

internal class LiveAndroidXFragmentDestroyWatcher(
private val objectWatcher: ObjectWatcher,
private val configProvider: () -> Config
) : (Activity) -> Unit {

private val fragmentLifecycleCallbacks = object : FragmentManager.FragmentLifecycleCallbacks() {

override fun onFragmentCreated(
fm: FragmentManager,
fragment: Fragment,
savedInstanceState: Bundle?
) {
ViewModelClearedWatcher.install(fragment, objectWatcher, configProvider)
}

override fun onFragmentViewDestroyed(
fm: FragmentManager,
fragment: Fragment
) {
val view = fragment.view
if (view != null && configProvider().watchFragmentViews) {
Log.d("LiveLeakCanary", "X onFragmentViewDestroyed fragment.localClassName = ${fragment::class.java.name}")
if (fragment::class.java.name.contains("live")) {
objectWatcher.watch(
view, "${fragment::class.java.name} received Fragment#onDestroyView() callback " +
"(references to its views should be cleared to prevent leaks)"
)
}
}
}

override fun onFragmentDestroyed(
fm: FragmentManager,
fragment: Fragment
) {
if (configProvider().watchFragments) {
Log.d("LiveLeakCanary", "X onFragmentDestroyed fragment.localClassName = ${fragment::class.java.name}")
if (fragment::class.java.name.contains("live")) {
objectWatcher.watch(
fragment, "${fragment::class.java.name} received Fragment#onDestroy() callback"
)
}
}
}
}

override fun invoke(activity: Activity) {
if (activity is FragmentActivity) {
val supportFragmentManager = activity.supportFragmentManager
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, true)
ViewModelClearedWatcher.install(activity, objectWatcher, configProvider)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# AndroidSupportFragmentDestroyWatcher is loaded via reflection
-keep class leakcanary.internal.AndroidSupportFragmentDestroyWatcher { *; }
-keep class leakcanary.internal.LiveAndroidSupportFragmentDestroyWatcher { *; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (C) 2019 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package leakcanary.internal

import android.app.Activity
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentActivity
import android.support.v4.app.FragmentManager
import android.util.Log
import leakcanary.AppWatcher.Config
import leakcanary.ObjectWatcher

internal class LiveAndroidSupportFragmentDestroyWatcher(
private val objectWatcher: ObjectWatcher,
private val configProvider: () -> Config
) : (Activity) -> Unit {

private val fragmentLifecycleCallbacks = object : FragmentManager.FragmentLifecycleCallbacks() {

override fun onFragmentViewDestroyed(
fm: FragmentManager,
fragment: Fragment
) {
val view = fragment.view
if (view != null && configProvider().watchFragmentViews) {
Log.d("LiveLeakCanary", "Support onFragmentViewDestroyed fragment.localClassName = ${fragment::class.java.name}")
if (fragment::class.java.name.contains("live")) {
objectWatcher.watch(
view, "${fragment::class.java.name} received Fragment#onDestroyView() callback " +
"(references to its views should be cleared to prevent leaks)"
)
}
}
}

override fun onFragmentDestroyed(
fm: FragmentManager,
fragment: Fragment
) {
if (configProvider().watchFragments) {
Log.d("LiveLeakCanary", "Support onFragmentViewDestroyed fragment.localClassName = ${fragment::class.java.name}")
if (fragment::class.java.name.contains("live")) {
objectWatcher.watch(
fragment, "${fragment::class.java.name} received Fragment#onDestroy() callback"
)
}
}
}
}

override fun invoke(activity: Activity) {
if (activity is FragmentActivity) {
val supportFragmentManager = activity.supportFragmentManager
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, true)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ internal object FragmentDestroyWatcher {

private const val ANDROIDX_FRAGMENT_CLASS_NAME = "androidx.fragment.app.Fragment"
private const val ANDROIDX_FRAGMENT_DESTROY_WATCHER_CLASS_NAME =
"leakcanary.internal.AndroidXFragmentDestroyWatcher"
"leakcanary.internal.LiveAndroidXFragmentDestroyWatcher"

// Using a string builder to prevent Jetifier from changing this string to Android X Fragment
@Suppress("VariableNaming", "PropertyName")
private val ANDROID_SUPPORT_FRAGMENT_CLASS_NAME =
StringBuilder("android.").append("support.v4.app.Fragment")
.toString()
private const val ANDROID_SUPPORT_FRAGMENT_DESTROY_WATCHER_CLASS_NAME =
"leakcanary.internal.AndroidSupportFragmentDestroyWatcher"
"leakcanary.internal.LiveAndroidSupportFragmentDestroyWatcher"

fun install(
application: Application,
Expand All @@ -50,7 +50,7 @@ internal object FragmentDestroyWatcher {

if (SDK_INT >= O) {
fragmentDestroyWatchers.add(
AndroidOFragmentDestroyWatcher(objectWatcher, configProvider)
LiveAndroidOFragmentDestroyWatcher(objectWatcher, configProvider)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ internal object InternalAppWatcher {
InternalAppWatcher.application = application

val configProvider = { AppWatcher.config }
ActivityDestroyWatcher.install(application, objectWatcher, configProvider)
LiveActivityDestroyWatcher.install(application, objectWatcher, configProvider)
FragmentDestroyWatcher.install(application, objectWatcher, configProvider)
onAppWatcherInstalled(application)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package leakcanary.internal

import android.app.Activity
import android.app.Application
import android.util.Log
import leakcanary.AppWatcher
import leakcanary.ObjectWatcher

/**
*
* @ClassName: LiveActivityDestroyWatcher
* @Description: 只检查live相关的类
* @CreateDate: 2020/5/20 14:14
* @Version: 1.0
*/
internal class LiveActivityDestroyWatcher private constructor(
private val objectWatcher: ObjectWatcher,
private val configProvider: () -> AppWatcher.Config
) {

private val lifecycleCallbacks =
object : Application.ActivityLifecycleCallbacks by InternalAppWatcher.noOpDelegate() {
override fun onActivityDestroyed(activity: Activity) {
if (configProvider().watchActivities) {
Log.d("LiveLeakCanary", "onActivityDestroyed activity.localClassName = ${activity::class.java.name}")
if (activity::class.java.name.contains("live")) {
objectWatcher.watch(
activity, "${activity::class.java.name} received Activity#onDestroy() callback"
)
}
}
}
}

companion object {
fun install(
application: Application,
objectWatcher: ObjectWatcher,
configProvider: () -> AppWatcher.Config
) {
val activityDestroyWatcher =
LiveActivityDestroyWatcher(objectWatcher, configProvider)
application.registerActivityLifecycleCallbacks(activityDestroyWatcher.lifecycleCallbacks)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (C) 2018 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:Suppress("DEPRECATION")

package leakcanary.internal

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Fragment
import android.app.FragmentManager
import android.util.Log
import leakcanary.AppWatcher.Config
import leakcanary.ObjectWatcher

@SuppressLint("NewApi")
internal class LiveAndroidOFragmentDestroyWatcher(
private val objectWatcher: ObjectWatcher,
private val configProvider: () -> Config
) : (Activity) -> Unit {
private val fragmentLifecycleCallbacks = object : FragmentManager.FragmentLifecycleCallbacks() {

override fun onFragmentViewDestroyed(
fm: FragmentManager,
fragment: Fragment
) {
val view = fragment.view
if (view != null && configProvider().watchFragmentViews) {
Log.d("LiveLeakCanary", "O onFragmentViewDestroyed fragment.localClassName = ${fragment::class.java.name}")
if (fragment::class.java.name.contains("live")) {
objectWatcher.watch(
view, "${fragment::class.java.name} received Fragment#onDestroyView() callback " +
"(references to its views should be cleared to prevent leaks)"
)
}
}
}

override fun onFragmentDestroyed(
fm: FragmentManager,
fragment: Fragment
) {
if (configProvider().watchFragments) {
Log.d("LiveLeakCanary", "O onFragmentDestroyed fragment.localClassName = ${fragment::class.java.name}")
if (fragment::class.java.name.contains("live")) {
objectWatcher.watch(
fragment, "${fragment::class.java.name} received Fragment#onDestroy() callback"
)
}
}
}
}

override fun invoke(activity: Activity) {
val fragmentManager = activity.fragmentManager
fragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, true)
}
}

0 comments on commit e72cf61

Please sign in to comment.