退出Activity时清理bitmap
退出LiveActivity时,清理SVGA 新增检测到触发未捕获异常闪退时,直接退出不再重新加载 优化一处LiveActivity所持有的静态view,防止内存泄漏 更新SVGAPlayer库
This commit is contained in:
parent
39b4a52ade
commit
dd97d35851
@ -6,6 +6,7 @@ import android.content.Context;
|
|||||||
import android.net.http.HttpResponseCache;
|
import android.net.http.HttpResponseCache;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.os.Process;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ import com.yunbao.common.BuildConfig;
|
|||||||
import com.yunbao.common.CommonAppConfig;
|
import com.yunbao.common.CommonAppConfig;
|
||||||
import com.yunbao.common.CommonAppContext;
|
import com.yunbao.common.CommonAppContext;
|
||||||
import com.yunbao.common.Constants;
|
import com.yunbao.common.Constants;
|
||||||
|
import com.yunbao.common.glide.ImgLoader;
|
||||||
import com.yunbao.common.http.CommonHttpUtil;
|
import com.yunbao.common.http.CommonHttpUtil;
|
||||||
import com.yunbao.common.http.HttpCallback;
|
import com.yunbao.common.http.HttpCallback;
|
||||||
import com.yunbao.common.manager.imrongcloud.InstructorSendReward;
|
import com.yunbao.common.manager.imrongcloud.InstructorSendReward;
|
||||||
@ -47,7 +49,9 @@ import com.yunbao.main.activity.MsgSettActivity;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import io.rong.imkit.config.RongConfigCenter;
|
import io.rong.imkit.config.RongConfigCenter;
|
||||||
import io.rong.imlib.RongIMClient;
|
import io.rong.imlib.RongIMClient;
|
||||||
@ -72,6 +76,7 @@ public class AppContext extends CommonAppContext {
|
|||||||
|
|
||||||
public static AppContext sInstance;
|
public static AppContext sInstance;
|
||||||
public LiveImDeletUtil liveImDeletUtil;
|
public LiveImDeletUtil liveImDeletUtil;
|
||||||
|
private final static List<WeakReference<Activity>> activities = new ArrayList<>();
|
||||||
|
|
||||||
private static final class AdjustLifecycleCallbacks implements ActivityLifecycleCallbacks {
|
private static final class AdjustLifecycleCallbacks implements ActivityLifecycleCallbacks {
|
||||||
@Override
|
@Override
|
||||||
@ -96,12 +101,12 @@ public class AppContext extends CommonAppContext {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityDestroyed(@NonNull Activity activity) {
|
public void onActivityDestroyed(@NonNull Activity activity) {
|
||||||
|
activities.remove(activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
|
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
|
||||||
|
activities.add(new WeakReference<>(activity));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -115,7 +120,7 @@ public class AppContext extends CommonAppContext {
|
|||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
//注册全局异常捕获
|
//注册全局异常捕获
|
||||||
// registerError();
|
registerError();
|
||||||
sInstance = this;
|
sInstance = this;
|
||||||
L.setDeBug(BuildConfig.DEBUG);
|
L.setDeBug(BuildConfig.DEBUG);
|
||||||
AppEventsLogger.activateApp(this);
|
AppEventsLogger.activateApp(this);
|
||||||
@ -288,6 +293,14 @@ public class AppContext extends CommonAppContext {
|
|||||||
.setMainCrashHandler((t, e) -> {
|
.setMainCrashHandler((t, e) -> {
|
||||||
Log.e("ApplicationError", "主线程异常");//此处log只是展示,当debug为true时,主类内部log会打印异常信息
|
Log.e("ApplicationError", "主线程异常");//此处log只是展示,当debug为true时,主类内部log会打印异常信息
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
//闪退后finish所有Activity并且杀死进程
|
||||||
|
for (WeakReference<Activity> activity : activities) {
|
||||||
|
if (activity != null) {
|
||||||
|
activity.get().finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Process.killProcess(Process.myPid());
|
||||||
|
System.exit(0);
|
||||||
})
|
})
|
||||||
.setUncaughtCrashHandler((t, e) -> {
|
.setUncaughtCrashHandler((t, e) -> {
|
||||||
Log.e("ApplicationError", "子线程异常");//此处log只是展示,当debug为true时,主类内部log会打印异常信息
|
Log.e("ApplicationError", "子线程异常");//此处log只是展示,当debug为true时,主类内部log会打印异常信息
|
||||||
|
@ -46,7 +46,7 @@ public class NeverCrashUtils {
|
|||||||
* 注意跨线程操作的可能
|
* 注意跨线程操作的可能
|
||||||
*/
|
*/
|
||||||
public NeverCrashUtils setMainCrashHandler(MainCrashHandler mainCrashHandler) {
|
public NeverCrashUtils setMainCrashHandler(MainCrashHandler mainCrashHandler) {
|
||||||
mainCrashHandler = mainCrashHandler;
|
this.mainCrashHandler = mainCrashHandler;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,6 +98,7 @@ public class NeverCrashUtils {
|
|||||||
Toast.makeText(application, "发生闪退", Toast.LENGTH_SHORT).show();
|
Toast.makeText(application, "发生闪退", Toast.LENGTH_SHORT).show();
|
||||||
// FileUtil.saveStringToFile(new File(application.getDir("files", Context.MODE_PRIVATE).getAbsolutePath()),throwableToString(e),"error.log");
|
// FileUtil.saveStringToFile(new File(application.getDir("files", Context.MODE_PRIVATE).getAbsolutePath()),throwableToString(e),"error.log");
|
||||||
getMainCrashHandler().mainException(Looper.getMainLooper().getThread(), e);
|
getMainCrashHandler().mainException(Looper.getMainLooper().getThread(), e);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -24,6 +24,7 @@ import androidx.annotation.Nullable;
|
|||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
import com.yunbao.common.R;
|
import com.yunbao.common.R;
|
||||||
|
import com.yunbao.common.glide.ImgLoader;
|
||||||
import com.yunbao.common.interfaces.LifeCycleListener;
|
import com.yunbao.common.interfaces.LifeCycleListener;
|
||||||
import com.yunbao.common.utils.ClickUtil;
|
import com.yunbao.common.utils.ClickUtil;
|
||||||
|
|
||||||
@ -136,6 +137,7 @@ public abstract class AbsActivity extends AppCompatActivity {
|
|||||||
mLifeCycleListeners.clear();
|
mLifeCycleListeners.clear();
|
||||||
mLifeCycleListeners = null;
|
mLifeCycleListeners = null;
|
||||||
}
|
}
|
||||||
|
ImgLoader.clearMemory(this);
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,18 @@ package com.yunbao.common.utils;
|
|||||||
import com.opensource.svgaplayer.SVGACallback;
|
import com.opensource.svgaplayer.SVGACallback;
|
||||||
import com.opensource.svgaplayer.SVGAImageView;
|
import com.opensource.svgaplayer.SVGAImageView;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class SVGAViewUtils {
|
public class SVGAViewUtils {
|
||||||
|
private final static List<SVGAImageView> SVGA_CACHE = new ArrayList<>();
|
||||||
|
|
||||||
public static void playEndClear(SVGAImageView svga, boolean isClear) {
|
public static void playEndClear(SVGAImageView svga, boolean isClear) {
|
||||||
|
if (!isClear) {
|
||||||
|
if (!SVGA_CACHE.contains(svga)) {
|
||||||
|
SVGA_CACHE.add(svga);
|
||||||
|
}
|
||||||
|
}
|
||||||
svga.setCallback(new SVGACallback() {
|
svga.setCallback(new SVGACallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
@ -31,6 +41,20 @@ public class SVGAViewUtils {
|
|||||||
});
|
});
|
||||||
svga.startAnimation();
|
svga.startAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized static void clearSVGA() {
|
||||||
|
for (SVGAImageView view : SVGA_CACHE) {
|
||||||
|
try {
|
||||||
|
if (view != null) {
|
||||||
|
view.clear();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SVGA_CACHE.clear();
|
||||||
|
}
|
||||||
|
|
||||||
public static void playEndClear(SVGAImageView svga) {
|
public static void playEndClear(SVGAImageView svga) {
|
||||||
playEndClear(svga, true);
|
playEndClear(svga, true);
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
BIN
libs/svgaplayer-release-v1.1.aar
Normal file
BIN
libs/svgaplayer-release-v1.1.aar
Normal file
Binary file not shown.
@ -1 +1 @@
|
|||||||
apply plugin: 'com.android.library'
apply plugin: 'img-optimizer'
apply plugin: 'kotlin-android'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
aaptOptions.cruncherEnabled = false
aaptOptions.useNewCruncher = false
packagingOptions {
pickFirst "lib/armeabi/libyuvutils.so"
pickFirst "lib/arm64-v8a/libyuvutils.so"
pickFirst "lib/armeabi-v7a/libyuvutils.so"
pickFirst "lib/armeabi/libyuvtools.so"
pickFirst "lib/arm64-v8a/libyuvtools.so"
pickFirst "lib/armeabi-v7a/libyuvtools.so"
exclude "lib/arm64-v8a/libmmcv_api_handgesture.so"
exclude "lib/arm64-v8a/libmmcv_api_express.so"
exclude "lib/arm64-v8a/libMediaEncoder.so"
exclude "lib/arm64-v8a/libarcore_sdk_c.so"
exclude "lib/arm64-v8a/libmediadecoder.so"
exclude "lib/arm64-v8a/libMediaMuxer.so"
exclude "lib/arm64-v8a/libarcore_sdk_jni.so"
exclude "lib/arm64-v8a/libMediaUtils.so"
exclude "lib/arm64-v8a/libcosmosffmpeg.so"
}
defaultConfig {
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
manifestPlaceholders = rootProject.ext.manifestPlaceholders
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
aaptOptions {
cruncherEnabled = false
useNewCruncher = false
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
kotlinOptions {
allWarningsAsErrors = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
repositories {
flatDir {
dirs 'libs', '../libs'
}
mavenCentral()
}
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.0'
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
implementation (name:'../libs/beautysdk-202202241203',ext:'aar')
implementation (name:'../libs/library-release',ext:'aar')
//socket.io
implementation('io.socket:socket.io-client:1.0.0') {
exclude group: 'org.json', module: 'json'
}
//common
api project(path: ':common')
// api project(path:':FaceUnity')//新娱美颜
annotationProcessor rootProject.ext.dependencies["arouter-compiler"]
//工具
api rootProject.ext.dependencies["blank-utilcode"]
implementation 'com.eightbitlab:blurview:1.6.6'
implementation 'com.google.code.gson:gson:2.8.6'
implementation "com.getkeepsafe.relinker:relinker:1.4.4"
}
|
apply plugin: 'com.android.library'
apply plugin: 'img-optimizer'
apply plugin: 'kotlin-android'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
aaptOptions.cruncherEnabled = false
aaptOptions.useNewCruncher = false
packagingOptions {
pickFirst "lib/armeabi/libyuvutils.so"
pickFirst "lib/arm64-v8a/libyuvutils.so"
pickFirst "lib/armeabi-v7a/libyuvutils.so"
pickFirst "lib/armeabi/libyuvtools.so"
pickFirst "lib/arm64-v8a/libyuvtools.so"
pickFirst "lib/armeabi-v7a/libyuvtools.so"
exclude "lib/arm64-v8a/libmmcv_api_handgesture.so"
exclude "lib/arm64-v8a/libmmcv_api_express.so"
exclude "lib/arm64-v8a/libMediaEncoder.so"
exclude "lib/arm64-v8a/libarcore_sdk_c.so"
exclude "lib/arm64-v8a/libmediadecoder.so"
exclude "lib/arm64-v8a/libMediaMuxer.so"
exclude "lib/arm64-v8a/libarcore_sdk_jni.so"
exclude "lib/arm64-v8a/libMediaUtils.so"
exclude "lib/arm64-v8a/libcosmosffmpeg.so"
}
defaultConfig {
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
manifestPlaceholders = rootProject.ext.manifestPlaceholders
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
aaptOptions {
cruncherEnabled = false
useNewCruncher = false
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
kotlinOptions {
allWarningsAsErrors = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
repositories {
flatDir {
dirs 'libs', '../libs'
}
mavenCentral()
}
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.0'
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
implementation (name:'../libs/beautysdk-202202241203',ext:'aar')
implementation (name:'../libs/svgaplayer-release-v1.1',ext:'aar')
//socket.io
implementation('io.socket:socket.io-client:1.0.0') {
exclude group: 'org.json', module: 'json'
}
//common
api project(path: ':common')
// api project(path:':FaceUnity')//新娱美颜
annotationProcessor rootProject.ext.dependencies["arouter-compiler"]
//工具
api rootProject.ext.dependencies["blank-utilcode"]
implementation 'com.eightbitlab:blurview:1.6.6'
implementation 'com.google.code.gson:gson:2.8.6'
implementation "com.getkeepsafe.relinker:relinker:1.4.4"
}
|
@ -34,6 +34,7 @@ import com.yunbao.common.interfaces.KeyBoardHeightChangeListener;
|
|||||||
import com.yunbao.common.utils.KeyBoardHeightUtil2;
|
import com.yunbao.common.utils.KeyBoardHeightUtil2;
|
||||||
import com.yunbao.common.utils.L;
|
import com.yunbao.common.utils.L;
|
||||||
import com.yunbao.common.utils.ProcessImageUtil;
|
import com.yunbao.common.utils.ProcessImageUtil;
|
||||||
|
import com.yunbao.common.utils.SVGAViewUtils;
|
||||||
import com.yunbao.common.utils.ToastUtil;
|
import com.yunbao.common.utils.ToastUtil;
|
||||||
import com.yunbao.common.utils.WordUtil;
|
import com.yunbao.common.utils.WordUtil;
|
||||||
import com.yunbao.common.utils.formatBigNum;
|
import com.yunbao.common.utils.formatBigNum;
|
||||||
@ -103,7 +104,7 @@ import java.util.Objects;
|
|||||||
|
|
||||||
public abstract class LiveActivity extends AbsActivity implements SocketMessageListener, LiveShareDialogFragment.ActionListener, KeyBoardHeightChangeListener {
|
public abstract class LiveActivity extends AbsActivity implements SocketMessageListener, LiveShareDialogFragment.ActionListener, KeyBoardHeightChangeListener {
|
||||||
|
|
||||||
public static ViewGroup mContainer;
|
public ViewGroup mContainer;
|
||||||
protected ViewGroup mPageContainer;
|
protected ViewGroup mPageContainer;
|
||||||
protected LiveRoomViewHolder mLiveRoomViewHolder;
|
protected LiveRoomViewHolder mLiveRoomViewHolder;
|
||||||
protected AbsLiveViewHolder mLiveBottomViewHolder;
|
protected AbsLiveViewHolder mLiveBottomViewHolder;
|
||||||
@ -1520,6 +1521,7 @@ public abstract class LiveActivity extends AbsActivity implements SocketMessageL
|
|||||||
mLiveLuckGiftTipViewHolder = null;
|
mLiveLuckGiftTipViewHolder = null;
|
||||||
// mMobShareUtil = null;
|
// mMobShareUtil = null;
|
||||||
mImageUtil = null;
|
mImageUtil = null;
|
||||||
|
SVGAViewUtils.clearSVGA();
|
||||||
L.e("LiveActivity--------release------>");
|
L.e("LiveActivity--------release------>");
|
||||||
|
|
||||||
Constants.isSend = "0";
|
Constants.isSend = "0";
|
||||||
|
@ -172,6 +172,7 @@ public class LiveRyAnchorActivity extends LiveActivity implements LiveFunctionCl
|
|||||||
mBeautySdkType = CommonAppConfig.getInstance().getBeautySdkType();
|
mBeautySdkType = CommonAppConfig.getInstance().getBeautySdkType();
|
||||||
|
|
||||||
mLivePushViewHolder = new LivePushRyViewHolder(mContext, (ViewGroup) findViewById(R.id.preview_container));
|
mLivePushViewHolder = new LivePushRyViewHolder(mContext, (ViewGroup) findViewById(R.id.preview_container));
|
||||||
|
mLivePushViewHolder.setLiveActivityContainer(mContainer);
|
||||||
|
|
||||||
mLivePushViewHolder.addToParent();
|
mLivePushViewHolder.addToParent();
|
||||||
mLivePushViewHolder.subscribeActivityLifeCycle();
|
mLivePushViewHolder.subscribeActivityLifeCycle();
|
||||||
|
@ -102,6 +102,8 @@ public class LivePushRyViewHolder extends AbsRyLivePushViewHolder implements ITX
|
|||||||
public static RCRTCRoom rtcRoom;
|
public static RCRTCRoom rtcRoom;
|
||||||
public static RCRTCLiveInfo rcrtcLiveInfo;
|
public static RCRTCLiveInfo rcrtcLiveInfo;
|
||||||
|
|
||||||
|
private ViewGroup liveActivityContainer;
|
||||||
|
|
||||||
public LivePushRyViewHolder(Context context, ViewGroup parentView) {
|
public LivePushRyViewHolder(Context context, ViewGroup parentView) {
|
||||||
super(context, parentView);
|
super(context, parentView);
|
||||||
this.contexts = context;
|
this.contexts = context;
|
||||||
@ -112,6 +114,9 @@ public class LivePushRyViewHolder extends AbsRyLivePushViewHolder implements ITX
|
|||||||
return R.layout.view_live_push_ry;
|
return R.layout.view_live_push_ry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLiveActivityContainer(ViewGroup liveActivityContainer) {
|
||||||
|
this.liveActivityContainer = liveActivityContainer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主房间事件监听
|
* 主房间事件监听
|
||||||
@ -194,7 +199,7 @@ public class LivePushRyViewHolder extends AbsRyLivePushViewHolder implements ITX
|
|||||||
if (mLiveRyLinkMicPkPresenter != null) {
|
if (mLiveRyLinkMicPkPresenter != null) {
|
||||||
mLiveRyLinkMicPkPresenter.onLinkDRMicPkApply(userBean);
|
mLiveRyLinkMicPkPresenter.onLinkDRMicPkApply(userBean);
|
||||||
} else {
|
} else {
|
||||||
mLiveRyLinkMicPkPresenter = new LiveRyLinkMicPkPresenter(mContext, mLivePushViewHolder, true, LiveActivity.mContainer);
|
mLiveRyLinkMicPkPresenter = new LiveRyLinkMicPkPresenter(mContext, mLivePushViewHolder, true, liveActivityContainer);
|
||||||
mLiveRyLinkMicPkPresenter.onLinkDRMicPkApply(userBean);
|
mLiveRyLinkMicPkPresenter.onLinkDRMicPkApply(userBean);
|
||||||
}
|
}
|
||||||
} else if (extra.equals("LiveDRPK1")) {
|
} else if (extra.equals("LiveDRPK1")) {
|
||||||
|
@ -66,7 +66,7 @@ dependencies {
|
|||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
compileOnly files('../libs/beautysdk-202202241203.aar')
|
compileOnly files('../libs/beautysdk-202202241203.aar')
|
||||||
compileOnly files('../libs/library-release.aar')
|
compileOnly files('../libs/svgaplayer-release-v1.1.aar')
|
||||||
//直播
|
//直播
|
||||||
api project(':live')
|
api project(':live')
|
||||||
//短视频
|
//短视频
|
||||||
|
@ -544,7 +544,7 @@ public class MainListAdapter extends RefreshAdapter<ListBean> {
|
|||||||
public void onComplete(SVGAVideoEntity videoItem) {
|
public void onComplete(SVGAVideoEntity videoItem) {
|
||||||
SVGADrawable drawable = new SVGADrawable(videoItem);
|
SVGADrawable drawable = new SVGADrawable(videoItem);
|
||||||
svga.setImageDrawable(drawable);
|
svga.setImageDrawable(drawable);
|
||||||
svga.startAnimation();
|
SVGAViewUtils.playEndClear(svga,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user