优化 opencv内存泄漏问题
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
var url = "https://www.autojs.org/assets/uploads/profile/3-profileavatar.png";
|
||||
var logo = null;
|
||||
var currentImg = null;
|
||||
|
||||
ui.layout(
|
||||
<vertical>
|
||||
@@ -18,7 +19,14 @@ ui.layout(
|
||||
//把一张图片设置到图片控件中
|
||||
function setImage(img) {
|
||||
ui.run(() => {
|
||||
var curImg = currentImg;
|
||||
if(oldImg != null){
|
||||
ui.post(()=>{
|
||||
oldImg.recycle();
|
||||
});
|
||||
}
|
||||
ui.img.setImageBitmap(img.bitmap);
|
||||
currentImg = img;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -63,20 +71,20 @@ ui.hsv.on("click", () => {
|
||||
|
||||
ui.blur.on("click", () => {
|
||||
processImg(img => {
|
||||
//RGB转HSV
|
||||
//模糊
|
||||
return images.blur(img, [10, 10]);
|
||||
});
|
||||
});
|
||||
|
||||
ui.medianBlur.on("click", () => {
|
||||
processImg(img => {
|
||||
//RGB转HSV
|
||||
return images.medianBlur(img, 10);
|
||||
//中值滤波
|
||||
return images.medianBlur(img, 5);
|
||||
});
|
||||
});
|
||||
ui.gaussianBlur.on("click", () => {
|
||||
processImg(img => {
|
||||
//RGB转HSV
|
||||
//高斯模糊
|
||||
return images.gaussianBlur(img, [5, 5]);
|
||||
});
|
||||
});
|
||||
@@ -14,7 +14,6 @@ import com.bumptech.glide.request.transition.Transition;
|
||||
import com.flurry.android.FlurryAgent;
|
||||
import com.squareup.leakcanary.LeakCanary;
|
||||
import com.stardust.app.GlobalAppContext;
|
||||
import com.stardust.autojs.core.image.OpenCVHelper;
|
||||
import com.stardust.autojs.core.ui.inflater.ImageLoader;
|
||||
import com.stardust.autojs.core.ui.inflater.util.Drawables;
|
||||
import com.stardust.theme.ThemeColor;
|
||||
@@ -31,8 +30,6 @@ import org.autojs.autojs.timing.TimedTaskManager;
|
||||
import org.autojs.autojs.timing.TimedTaskScheduler;
|
||||
import org.autojs.autojs.tool.CrashHandler;
|
||||
import org.autojs.autojs.ui.error.ErrorReportActivity;
|
||||
import org.opencv.android.BaseLoaderCallback;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -45,8 +45,7 @@ import static org.autojs.autojs.ui.edit.EditorView.EXTRA_READ_ONLY;
|
||||
* Created by Stardust on 2017/1/29.
|
||||
*/
|
||||
@EActivity(R.layout.activity_edit)
|
||||
public class
|
||||
EditActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHost, PermissionRequestProxyActivity {
|
||||
public class EditActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHost, PermissionRequestProxyActivity {
|
||||
|
||||
private OnActivityResultDelegate.Mediator mMediator = new OnActivityResultDelegate.Mediator();
|
||||
private static final String LOG_TAG = "EditActivity";
|
||||
|
||||
@@ -9,7 +9,7 @@ import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.stardust.autojs.core.image.OpenCVHelper;
|
||||
import com.stardust.autojs.core.opencv.OpenCVHelper;
|
||||
import com.xcy8.ads.listener.LoadAdListener;
|
||||
import com.xcy8.ads.view.FullScreenAdView;
|
||||
|
||||
|
||||
@@ -283,7 +283,7 @@ module.exports = function (__runtime__, scope) {
|
||||
}
|
||||
|
||||
function newMat() {
|
||||
return new org.opencv.core.Mat();
|
||||
return new com.stardust.autojs.core.opencv.Mat();
|
||||
}
|
||||
|
||||
function matToImage(mat) {
|
||||
|
||||
@@ -4,11 +4,14 @@ import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
|
||||
import com.stardust.autojs.core.opencv.MatOfPoint;
|
||||
import com.stardust.autojs.core.opencv.OpenCVHelper;
|
||||
import com.stardust.util.ScreenMetrics;
|
||||
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfPoint;
|
||||
|
||||
import com.stardust.autojs.core.opencv.Mat;
|
||||
|
||||
import org.opencv.core.Point;
|
||||
import org.opencv.core.Rect;
|
||||
import org.opencv.core.Scalar;
|
||||
@@ -48,6 +51,7 @@ public class ColorFinder {
|
||||
point.x = mScreenMetrics.scaleX((int) (point.x + rect.x));
|
||||
point.y = mScreenMetrics.scaleX((int) (point.y + rect.y));
|
||||
}
|
||||
OpenCVHelper.release(matOfPoint);
|
||||
return point;
|
||||
}
|
||||
|
||||
@@ -86,7 +90,7 @@ public class ColorFinder {
|
||||
if (nonZeroPos.rows() == 0 || nonZeroPos.cols() == 0) {
|
||||
result = null;
|
||||
} else {
|
||||
result = new MatOfPoint(nonZeroPos);
|
||||
result = OpenCVHelper.newMatOfPoint(nonZeroPos);
|
||||
}
|
||||
OpenCVHelper.release(bi);
|
||||
OpenCVHelper.release(nonZeroPos);
|
||||
@@ -114,7 +118,7 @@ public class ColorFinder {
|
||||
x += startingPoint.x;
|
||||
y += startingPoint.y;
|
||||
if (x >= image.getWidth() || y >= image.getHeight()
|
||||
|| x < 0 || y < 0) {
|
||||
|| x < 0 || y < 0) {
|
||||
return false;
|
||||
}
|
||||
int c = image.pixel(x, y);
|
||||
|
||||
@@ -6,10 +6,11 @@ import android.media.Image;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
|
||||
import com.stardust.autojs.core.opencv.OpenCVHelper;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
|
||||
import org.opencv.android.Utils;
|
||||
import org.opencv.core.Mat;
|
||||
import com.stardust.autojs.core.opencv.Mat;
|
||||
import org.opencv.highgui.Highgui;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package com.stardust.autojs.core.image;
|
||||
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.util.TimingLogger;
|
||||
|
||||
import com.stardust.autojs.core.opencv.OpenCVHelper;
|
||||
import com.stardust.util.Nath;
|
||||
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import com.stardust.autojs.core.opencv.Mat;
|
||||
import org.opencv.core.Point;
|
||||
import org.opencv.core.Rect;
|
||||
import org.opencv.core.Size;
|
||||
@@ -100,6 +100,7 @@ public class TemplateMatching {
|
||||
}
|
||||
logger.addSplit("result:" + p);
|
||||
logger.dumpToLog();
|
||||
OpenCVHelper.release(matchResult);
|
||||
if (similarity < strictThreshold) {
|
||||
return null;
|
||||
}
|
||||
|
||||
108
autojs/src/main/java/com/stardust/autojs/core/opencv/Mat.java
Normal file
108
autojs/src/main/java/com/stardust/autojs/core/opencv/Mat.java
Normal file
@@ -0,0 +1,108 @@
|
||||
package com.stardust.autojs.core.opencv;
|
||||
|
||||
import com.stardust.util.ResourceMonitor;
|
||||
|
||||
import org.opencv.core.Range;
|
||||
import org.opencv.core.Rect;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.core.Size;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class Mat extends org.opencv.core.Mat implements ResourceMonitor.Resource {
|
||||
|
||||
private static Method nClone;
|
||||
|
||||
static {
|
||||
try {
|
||||
nClone = org.opencv.core.Mat.class.getDeclaredMethod("n_clone", long.class);
|
||||
nClone.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static final AtomicInteger sResourceId = new AtomicInteger();
|
||||
private volatile boolean mReleased = false;
|
||||
private final int mResourceId = sResourceId.incrementAndGet();
|
||||
|
||||
public Mat(long addr) {
|
||||
super(addr);
|
||||
ResourceMonitor.onOpen(this);
|
||||
}
|
||||
|
||||
public Mat() {
|
||||
super();
|
||||
ResourceMonitor.onOpen(this);
|
||||
}
|
||||
|
||||
public Mat(int rows, int cols, int type) {
|
||||
super(rows, cols, type);
|
||||
ResourceMonitor.onOpen(this);
|
||||
}
|
||||
|
||||
public Mat(Size size, int type) {
|
||||
super(size, type);
|
||||
ResourceMonitor.onOpen(this);
|
||||
}
|
||||
|
||||
public Mat(int rows, int cols, int type, Scalar s) {
|
||||
super(rows, cols, type, s);
|
||||
ResourceMonitor.onOpen(this);
|
||||
}
|
||||
|
||||
public Mat(Size size, int type, Scalar s) {
|
||||
super(size, type, s);
|
||||
ResourceMonitor.onOpen(this);
|
||||
}
|
||||
|
||||
public Mat(Mat m, Range rowRange, Range colRange) {
|
||||
super(m, rowRange, colRange);
|
||||
ResourceMonitor.onOpen(this);
|
||||
}
|
||||
|
||||
public Mat(Mat m, Range rowRange) {
|
||||
super(m, rowRange);
|
||||
ResourceMonitor.onOpen(this);
|
||||
}
|
||||
|
||||
public Mat(Mat m, Rect roi) {
|
||||
super(m, roi);
|
||||
ResourceMonitor.onOpen(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mat clone() {
|
||||
return new Mat(n_clone(this.nativeObj));
|
||||
}
|
||||
|
||||
protected long n_clone(long addr) {
|
||||
try {
|
||||
return (long) nClone.invoke(this, addr);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
super.release();
|
||||
mReleased = true;
|
||||
ResourceMonitor.onClose(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
if (!mReleased) {
|
||||
ResourceMonitor.onFinalize(this);
|
||||
super.release();
|
||||
}
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResourceId() {
|
||||
return mResourceId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.stardust.autojs.core.opencv;
|
||||
|
||||
import com.stardust.util.ResourceMonitor;
|
||||
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Point;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class MatOfPoint extends org.opencv.core.MatOfPoint implements ResourceMonitor.Resource {
|
||||
|
||||
private static final AtomicInteger sResourceId = new AtomicInteger();
|
||||
private volatile boolean mReleased = false;
|
||||
private final int mResourceId = sResourceId.incrementAndGet();
|
||||
|
||||
public MatOfPoint() {
|
||||
super();
|
||||
ResourceMonitor.onOpen(this);
|
||||
}
|
||||
|
||||
public MatOfPoint(long addr) {
|
||||
super(addr);
|
||||
ResourceMonitor.onOpen(this);
|
||||
}
|
||||
|
||||
public MatOfPoint(Mat m) {
|
||||
super(m);
|
||||
ResourceMonitor.onOpen(this);
|
||||
}
|
||||
|
||||
public MatOfPoint(Point... a) {
|
||||
super(a);
|
||||
ResourceMonitor.onOpen(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
super.release();
|
||||
mReleased = true;
|
||||
ResourceMonitor.onClose(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
if (!mReleased) {
|
||||
ResourceMonitor.onFinalize(this);
|
||||
super.release();
|
||||
}
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResourceId() {
|
||||
return mResourceId;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.stardust.autojs.core.image;
|
||||
package com.stardust.autojs.core.opencv;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.Nullable;
|
||||
@@ -9,7 +9,7 @@ import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import org.opencv.android.InstallCallbackInterface;
|
||||
import org.opencv.android.LoaderCallbackInterface;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
import org.opencv.core.Mat;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2018/4/2.
|
||||
@@ -24,6 +24,17 @@ public class OpenCVHelper {
|
||||
private static final String LOG_TAG = "OpenCVHelper";
|
||||
private static boolean mInitialized = false;
|
||||
|
||||
public static MatOfPoint newMatOfPoint(Mat mat){
|
||||
return new MatOfPoint(mat);
|
||||
}
|
||||
|
||||
public static void release(@Nullable MatOfPoint mat) {
|
||||
if (mat == null)
|
||||
return;
|
||||
mat.release();
|
||||
}
|
||||
|
||||
|
||||
public static void release(@Nullable Mat mat) {
|
||||
if (mat == null)
|
||||
return;
|
||||
@@ -12,14 +12,12 @@ import android.os.Handler;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.util.Base64;
|
||||
import android.view.Display;
|
||||
import android.view.Surface;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.stardust.autojs.annotation.ScriptVariable;
|
||||
import com.stardust.autojs.core.image.ColorFinder;
|
||||
import com.stardust.autojs.core.image.ImageWrapper;
|
||||
import com.stardust.autojs.core.image.OpenCVHelper;
|
||||
import com.stardust.autojs.core.opencv.OpenCVHelper;
|
||||
import com.stardust.autojs.core.image.capture.ScreenCaptureRequester;
|
||||
import com.stardust.autojs.core.image.capture.ScreenCapturer;
|
||||
import com.stardust.autojs.core.image.TemplateMatching;
|
||||
@@ -30,11 +28,9 @@ import com.stardust.concurrent.VolatileDispose;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
import com.stardust.util.ScreenMetrics;
|
||||
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.Mat;
|
||||
import com.stardust.autojs.core.opencv.Mat;
|
||||
import org.opencv.core.Point;
|
||||
import org.opencv.core.Rect;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
96
common/src/main/java/com/stardust/util/ResourceMonitor.java
Normal file
96
common/src/main/java/com/stardust/util/ResourceMonitor.java
Normal file
@@ -0,0 +1,96 @@
|
||||
// ResourceMonitor$onFinalize$1.java
|
||||
package com.stardust.util;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.stardust.BuildConfig;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public final class ResourceMonitor {
|
||||
|
||||
private static final String LOG_TAG = "ResourceTracer";
|
||||
private static final ConcurrentHashMap<Class<?>, SparseArray<UnclosedResourceException>> mResources;
|
||||
private static Handler mHandler;
|
||||
private static boolean mEnabled;
|
||||
|
||||
public static void onOpen(ResourceMonitor.Resource resource) {
|
||||
if (!mEnabled) {
|
||||
return;
|
||||
}
|
||||
SparseArray<UnclosedResourceException> map = mResources.get(resource.getClass());
|
||||
if (map == null) {
|
||||
map = new SparseArray<>();
|
||||
mResources.put(resource.getClass(), map);
|
||||
}
|
||||
int resourceId = resource.getResourceId();
|
||||
ResourceMonitor.UnclosedResourceException exception = new ResourceMonitor.UnclosedResourceException("id = " + resourceId + ", resource = " + resource);
|
||||
exception.fillInStackTrace();
|
||||
map.put(resourceId, exception);
|
||||
}
|
||||
|
||||
public static void onClose(ResourceMonitor.Resource resource) {
|
||||
if (!mEnabled) {
|
||||
return;
|
||||
}
|
||||
SparseArray map = mResources.get(resource.getClass());
|
||||
if (map != null) {
|
||||
map.remove(resource.getResourceId());
|
||||
}
|
||||
}
|
||||
|
||||
public static void onFinalize(ResourceMonitor.Resource resource) {
|
||||
if (!mEnabled) {
|
||||
return;
|
||||
}
|
||||
SparseArray<UnclosedResourceException> map = mResources.get(resource.getClass());
|
||||
if (map != null) {
|
||||
int indexOfKey = map.indexOfKey(resource.getResourceId());
|
||||
if (indexOfKey >= 0) {
|
||||
final ResourceMonitor.UnclosedResourceException unclosedResourceException = map.valueAt(indexOfKey);
|
||||
map.removeAt(indexOfKey);
|
||||
if (mHandler == null) {
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
mHandler.post(new Runnable() {
|
||||
public final void run() {
|
||||
throw new UnclosedResourceDetectedException(unclosedResourceException);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
mResources = new ConcurrentHashMap<>();
|
||||
mEnabled = BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
public static boolean isEnabled() {
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
public static void setEnabled(boolean mEnabled) {
|
||||
ResourceMonitor.mEnabled = mEnabled;
|
||||
}
|
||||
|
||||
public static final class UnclosedResourceException extends RuntimeException {
|
||||
public UnclosedResourceException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final class UnclosedResourceDetectedException extends RuntimeException {
|
||||
public UnclosedResourceDetectedException(ResourceMonitor.UnclosedResourceException cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
|
||||
public interface Resource {
|
||||
int getResourceId();
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import android.widget.Toast;
|
||||
|
||||
import com.stardust.auojs.inrt.autojs.AutoJs;
|
||||
import com.stardust.auojs.inrt.launch.GlobalProjectLauncher;
|
||||
import com.stardust.autojs.core.image.OpenCVHelper;
|
||||
import com.stardust.autojs.core.opencv.OpenCVHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
Reference in New Issue
Block a user