优化代码:解决JSView的内存泄露问题

This commit is contained in:
TonyJiangWJ 2021-12-07 22:43:36 +08:00
parent 7abe6d6bd1
commit 5fcfa88ae0
9 changed files with 51 additions and 18 deletions

View File

@ -20,10 +20,11 @@ import java.util.concurrent.Executors
*/
@SuppressLint("ViewConstructor")
class ScriptCanvasView(context: Context, private val mScriptRuntime: ScriptRuntime) : TextureView(context), TextureView.SurfaceTextureListener {
class ScriptCanvasView(context: Context, scriptRuntime: ScriptRuntime) : TextureView(context), TextureView.SurfaceTextureListener {
@Volatile
private var mDrawing = true
private val mEventEmitter: EventEmitter = EventEmitter(mScriptRuntime.bridges)
private val mEventEmitter: EventEmitter = EventEmitter(scriptRuntime.bridges)
private var mScriptRuntime: ScriptRuntime? = null
private var mDrawingThreadPool: ExecutorService? = null
@Volatile
private var mTimePerDraw = (1000 / 30).toLong()
@ -33,6 +34,7 @@ class ScriptCanvasView(context: Context, private val mScriptRuntime: ScriptRunti
init {
surfaceTextureListener = this
mScriptRuntime = scriptRuntime
}
fun setMaxFps(maxFps: Int) {
@ -53,7 +55,7 @@ class ScriptCanvasView(context: Context, private val mScriptRuntime: ScriptRunti
var time = SystemClock.uptimeMillis()
val scriptCanvas = ScriptCanvas()
try {
while (mDrawing && !mScriptRuntime.isStopped) {
while (mDrawing && !mScriptRuntime?.isStopped!!) {
canvas = lockCanvas()
scriptCanvas.setCanvas(canvas)
emit("draw", scriptCanvas, this@ScriptCanvasView)
@ -66,7 +68,7 @@ class ScriptCanvasView(context: Context, private val mScriptRuntime: ScriptRunti
time = SystemClock.uptimeMillis()
}
} catch (e: Exception) {
mScriptRuntime.exit(e)
mScriptRuntime?.exit(e)
mDrawing = false
} finally {
if (canvas != null) {
@ -158,6 +160,7 @@ class ScriptCanvasView(context: Context, private val mScriptRuntime: ScriptRunti
override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
mDrawing = false
mDrawingThreadPool?.shutdown()
mScriptRuntime = null
Log.d(LOG_TAG, "onSurfaceTextureDestroyed: ${this}")
return true
}
@ -166,6 +169,11 @@ class ScriptCanvasView(context: Context, private val mScriptRuntime: ScriptRunti
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
mScriptRuntime = null
}
companion object {
private const val LOG_TAG = "ScriptCanvasView"

View File

@ -52,12 +52,12 @@ public class ScreenCaptureRequestActivity extends Activity {
@Override
protected void onDestroy() {
super.onDestroy();
IntentExtras.fromIntentAndRelease(getIntent());
mCallback = null;
if (mScreenCaptureRequester == null)
return;
mScreenCaptureRequester.cancel();
mScreenCaptureRequester = null;
IntentExtras.fromIntentAndRelease(getIntent());
}
@Override

View File

@ -357,5 +357,9 @@ public class DynamicLayoutInflater {
return value.indexOf("}}", i + 1) >= 0;
}
public void recycle() {
setContext(null);
mViewAttrSetters.clear();
mViewCreators.clear();
}
}

View File

@ -15,6 +15,7 @@ import org.w3c.dom.NodeList;
import com.stardust.autojs.workground.WrapContentLinearLayoutManager;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
/**
@ -130,6 +131,12 @@ public class JsListView extends RecyclerView {
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
mScriptRuntime = null;
}
private class Adapter extends RecyclerView.Adapter<ViewHolder> {
@Override
@ -147,6 +154,9 @@ public class JsListView extends RecyclerView {
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
if (mScriptRuntime == null) {
return;
}
try {
Object oldCtx = mScriptRuntime.ui.getBindingContext();
Object item = mDataSourceAdapter.getItem(mDataSource, position);
@ -183,6 +193,18 @@ public class JsListView extends RecyclerView {
: mDataSourceAdapter == null ? 0
: mDataSourceAdapter.getItemCount(mDataSource);
}
@Override
public void onViewDetachedFromWindow(@NonNull ViewHolder holder) {
super.onViewDetachedFromWindow(holder);
mScriptRuntime = null;
}
@Override
public void onViewRecycled(@NonNull ViewHolder holder) {
super.onViewRecycled(holder);
mScriptRuntime = null;
}
}
}

View File

@ -1,7 +1,5 @@
package com.stardust.autojs.core.util
import com.stardust.autojs.core.internal.Functions
class ScriptPromiseAdapter {
interface Callback {
@ -36,11 +34,18 @@ class ScriptPromiseAdapter {
fun resolve(result: Any?) {
mResult = result
mResolveCallback?.call(result)
releaseCallbacks()
}
fun reject(error: Any?) {
mError = error
mRejectCallback?.call(error)
releaseCallbacks()
}
fun releaseCallbacks() {
mResolveCallback = null
mRejectCallback = null
}
companion object {

View File

@ -4,13 +4,10 @@ import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.MessageQueue;
import android.util.Log;
import com.stardust.autojs.core.looper.LooperHelper;
import com.stardust.autojs.script.JavaScriptSource;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.util.Callback;
import org.mozilla.javascript.ContinuationPending;

View File

@ -1,14 +1,10 @@
package com.stardust.autojs.runtime.api;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;
import android.util.SparseArray;
import com.stardust.autojs.core.looper.Timer;
import com.stardust.autojs.core.looper.TimerThread;
import com.stardust.autojs.runtime.ScriptBridges;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.concurrent.VolatileBox;
@ -90,6 +86,9 @@ public class Timers {
public void recycle() {
mMainTimer.removeAllCallbacks();
mUiTimer.removeAllCallbacks();
mUiTimer = null;
mMainTimer = null;
}
}

View File

@ -103,7 +103,7 @@ public class UI extends ProxyObject {
}
public void recycle() {
mDynamicLayoutInflater.setContext(null);
mDynamicLayoutInflater.recycle();
mRuntime = null;
}

View File

@ -1,8 +1,6 @@
package com.stardust.lang;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Set;
import java.util.WeakHashMap;