修复 画布canvas默认白色改成默认透明

修复 画布canvas会覆盖其他View的问题
This commit is contained in:
hyb1996
2019-01-14 23:39:47 +08:00
parent a0e9dbcc2e
commit 863af6badf
5 changed files with 192 additions and 189 deletions

View File

@@ -1,188 +0,0 @@
package com.stardust.autojs.core.graphics;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.SystemClock;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.stardust.autojs.core.eventloop.EventEmitter;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by Stardust on 2018/3/16.
*/
@SuppressLint("ViewConstructor")
public class ScriptCanvasView extends SurfaceView implements SurfaceHolder.Callback {
private static final String LOG_TAG = "ScriptCanvasView";
private volatile boolean mDrawing = true;
private EventEmitter mEventEmitter;
private final SurfaceHolder mHolder;
private ExecutorService mDrawingThreadPool;
private ScriptRuntime mScriptRuntime;
private volatile long mTimePerDraw = 1000 / 30;
public ScriptCanvasView(Context context, ScriptRuntime scriptRuntime) {
super(context);
mScriptRuntime = scriptRuntime;
mEventEmitter = new EventEmitter(mScriptRuntime.bridges);
mHolder = getHolder();
init();
}
public void setMaxFps(int maxFps) {
if (maxFps <= 0) {
mTimePerDraw = 0;
} else {
mTimePerDraw = 100 / maxFps;
}
}
private void init() {
mHolder.addCallback(this);
setZOrderOnTop(false);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
performDraw();
Log.d(LOG_TAG, "surfaceCreated: " + this);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
private synchronized void performDraw() {
if (mDrawingThreadPool != null)
return;
mDrawingThreadPool = Executors.newCachedThreadPool();
mDrawingThreadPool.execute(() -> {
Canvas canvas = null;
SurfaceHolder holder = getHolder();
long time = SystemClock.uptimeMillis();
ScriptCanvas scriptCanvas = new ScriptCanvas();
try {
while (mDrawing) {
canvas = holder.lockCanvas();
scriptCanvas.setCanvas(canvas);
scriptCanvas.drawColor(Color.WHITE);
emit("draw", scriptCanvas, ScriptCanvasView.this);
holder.unlockCanvasAndPost(canvas);
canvas = null;
long dt = mTimePerDraw - (SystemClock.uptimeMillis() - time);
if (dt > 0) {
sleep(dt);
}
time = SystemClock.uptimeMillis();
}
} catch (Exception e) {
mScriptRuntime.exit(e);
mDrawing = false;
} finally {
if (canvas != null) {
holder.unlockCanvasAndPost(canvas);
}
}
});
}
private void sleep(long dt) {
try {
Thread.sleep(dt);
} catch (InterruptedException e) {
throw new ScriptInterruptedException(e);
}
}
@Override
protected void onWindowVisibilityChanged(int visibility) {
Log.d(LOG_TAG, "onWindowVisibilityChanged: " + this + ": visibility=" + visibility + ", mDrawingThreadPool=" + mDrawingThreadPool);
if (visibility == VISIBLE) {
mDrawing = true;
} else {
mDrawing = false;
}
super.onWindowVisibilityChanged(visibility);
}
@Override
public synchronized void surfaceDestroyed(SurfaceHolder holder) {
mDrawing = false;
mDrawingThreadPool.shutdown();
mDrawingThreadPool = null;
Log.d(LOG_TAG, "surfaceDestroyed: " + this);
}
public EventEmitter once(String eventName, Object listener) {
return mEventEmitter.once(eventName, listener);
}
public EventEmitter on(String eventName, Object listener) {
return mEventEmitter.on(eventName, listener);
}
public EventEmitter addListener(String eventName, Object listener) {
return mEventEmitter.addListener(eventName, listener);
}
public boolean emit(String eventName, Object... args) {
return mEventEmitter.emit(eventName, args);
}
public String[] eventNames() {
return mEventEmitter.eventNames();
}
public int listenerCount(String eventName) {
return mEventEmitter.listenerCount(eventName);
}
public Object[] listeners(String eventName) {
return mEventEmitter.listeners(eventName);
}
public EventEmitter prependListener(String eventName, Object listener) {
return mEventEmitter.prependListener(eventName, listener);
}
public EventEmitter prependOnceListener(String eventName, Object listener) {
return mEventEmitter.prependOnceListener(eventName, listener);
}
public EventEmitter removeAllListeners() {
return mEventEmitter.removeAllListeners();
}
public EventEmitter removeAllListeners(String eventName) {
return mEventEmitter.removeAllListeners(eventName);
}
public EventEmitter removeListener(String eventName, Object listener) {
return mEventEmitter.removeListener(eventName, listener);
}
public EventEmitter setMaxListeners(int n) {
return mEventEmitter.setMaxListeners(n);
}
public int getMaxListeners() {
return mEventEmitter.getMaxListeners();
}
public static int defaultMaxListeners() {
return EventEmitter.defaultMaxListeners();
}
}

View File

@@ -0,0 +1,178 @@
package com.stardust.autojs.core.graphics
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.SurfaceTexture
import android.os.SystemClock
import android.util.Log
import android.view.TextureView
import android.view.View
import com.stardust.autojs.core.eventloop.EventEmitter
import com.stardust.autojs.runtime.ScriptRuntime
import com.stardust.autojs.runtime.exception.ScriptInterruptedException
import com.stardust.ext.ifNull
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
/**
* Created by Stardust on 2018/3/16.
*/
@SuppressLint("ViewConstructor")
class ScriptCanvasView(context: Context, private val mScriptRuntime: ScriptRuntime) : TextureView(context), TextureView.SurfaceTextureListener {
@Volatile
private var mDrawing = true
private val mEventEmitter: EventEmitter = EventEmitter(mScriptRuntime.bridges)
private var mDrawingThreadPool: ExecutorService? = null
@Volatile
private var mTimePerDraw = (1000 / 30).toLong()
val maxListeners: Int
get() = mEventEmitter.maxListeners
init {
surfaceTextureListener = this
}
fun setMaxFps(maxFps: Int) {
mTimePerDraw = if (maxFps <= 0) {
0
} else {
(100 / maxFps).toLong()
}
}
@Synchronized
private fun performDraw() {
::mDrawingThreadPool.ifNull {
Executors.newCachedThreadPool()
}.run {
execute {
var canvas: Canvas? = null
var time = SystemClock.uptimeMillis()
val scriptCanvas = ScriptCanvas()
try {
while (mDrawing) {
canvas = lockCanvas()
scriptCanvas.setCanvas(canvas)
// scriptCanvas.drawColor(Color.WHITE);
emit("draw", scriptCanvas, this@ScriptCanvasView)
unlockCanvasAndPost(canvas)
canvas = null
val dt = mTimePerDraw - (SystemClock.uptimeMillis() - time)
if (dt > 0) {
sleep(dt)
}
time = SystemClock.uptimeMillis()
}
} catch (e: Exception) {
mScriptRuntime.exit(e)
mDrawing = false
} finally {
if (canvas != null) {
unlockCanvasAndPost(canvas)
}
}
}
}
}
private fun sleep(dt: Long) {
try {
Thread.sleep(dt)
} catch (e: InterruptedException) {
throw ScriptInterruptedException(e)
}
}
override fun onWindowVisibilityChanged(visibility: Int) {
Log.d(LOG_TAG, "onWindowVisibilityChanged: " + this + ": visibility=" + visibility + ", mDrawingThreadPool=" + mDrawingThreadPool)
val oldDrawing = mDrawing
mDrawing = visibility == View.VISIBLE
if (!oldDrawing && mDrawing) {
performDraw()
}
super.onWindowVisibilityChanged(visibility)
}
fun once(eventName: String, listener: Any): EventEmitter {
return mEventEmitter.once(eventName, listener)
}
fun on(eventName: String, listener: Any): EventEmitter {
return mEventEmitter.on(eventName, listener)
}
fun addListener(eventName: String, listener: Any): EventEmitter {
return mEventEmitter.addListener(eventName, listener)
}
fun emit(eventName: String, vararg args: Any): Boolean {
return mEventEmitter.emit(eventName, *args)
}
fun eventNames(): Array<String> {
return mEventEmitter.eventNames()
}
fun listenerCount(eventName: String): Int {
return mEventEmitter.listenerCount(eventName)
}
fun listeners(eventName: String): Array<Any> {
return mEventEmitter.listeners(eventName)
}
fun prependListener(eventName: String, listener: Any): EventEmitter {
return mEventEmitter.prependListener(eventName, listener)
}
fun prependOnceListener(eventName: String, listener: Any): EventEmitter {
return mEventEmitter.prependOnceListener(eventName, listener)
}
fun removeAllListeners(): EventEmitter {
return mEventEmitter.removeAllListeners()
}
fun removeAllListeners(eventName: String): EventEmitter {
return mEventEmitter.removeAllListeners(eventName)
}
fun removeListener(eventName: String, listener: Any): EventEmitter {
return mEventEmitter.removeListener(eventName, listener)
}
fun setMaxListeners(n: Int): EventEmitter {
return mEventEmitter.setMaxListeners(n)
}
override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int) {
performDraw()
Log.d(LOG_TAG, "onSurfaceTextureAvailable: ${this}, width = $width, height = $height")
}
override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) {}
override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
mDrawing = false
mDrawingThreadPool?.shutdown()
Log.d(LOG_TAG, "onSurfaceTextureDestroyed: ${this}")
return true
}
override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {
}
companion object {
private const val LOG_TAG = "ScriptCanvasView"
fun defaultMaxListeners(): Int {
return EventEmitter.defaultMaxListeners()
}
}
}