我正在使用 Android Studio
目标:我想更新保持非 null 并mRecordingCanvas在MyCustomView.
即如果上次我从(0,0)到(0,100)画一条线,则不会重置null,
后来我使用自定义方法再次调用它continueRecording并从(0,100)到(100,100)再画一条线,
因此我不如果我想在 "same" 中再添加 10-100 行,则需要再次绘制所有内容mRecordingCanvas。
我希望添加
@NonNull
public Canvas continueRecording() {
return mRecordingCanvas;
}
并删除mRecordingCanvas = null;里面
public void endRecording() {
verifyValid();
if (mRecordingCanvas != null) {
mRequiresHwAcceleration = mRecordingCanvas.mHoldsHwBitmap;
//mRecordingCanvas = null;
nativeEndRecording(mNativePicture);
}
}
and remove // if (mRecordingCanvas != null) {
// throw new IllegalStateException("图片已经录制,必须调用 #endRecording()");
//}
并将PictureCanvas里面的变量改成(this, bitmap)
里面
@NonNull
public Canvas beginRecording(int width, int height) {
verifyValid();
if (mRecordingCanvas != null) {
throw new IllegalStateException("Picture already recording, must call #endRecording()");
}
//long ni = nativeBeginRecording(mNativePicture, width, height);
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mRecordingCanvas = new PictureCanvas(this, bitmap);
mRequiresHwAcceleration = false;
return mRecordingCanvas;
}
但是 android.graphics 包中的 Picture.java 存在一些问题;
(1)Picture.java有句@UnsupportedAppUsage(maxTargetSdk = 28),
但TargetSdk我APP的要Sdk=29,所以我可能需要做一个MyPicture.java
(2) 当我将 Picture.java 中的所有内容复制到 MyPicture.java 并删除
@UnsupportedAppUsage(maxTargetSdk = 28).
当我尝试使用Android Studio使用移动设备运行调试APP时出现一些问题(Sdk ver = 28),
调试日志显示找不到本机
public class MyCustomView extends View {
private MyPicture mPicture = new MyPicture();
protected void onDraw(Canvas canvas) {
if (initialTimeMillis == 0) {
//do sth
Canvas temp_canvas =
mPicture.beginRecording(MainActivity.global_int_widthpx,MainActivity.global_int_heightpx);
mPicture.endRecording();
initialTimeMillis = currentTimeMillis;
return;
}
Canvas temp_canvas = mPicture.continueRecording();
current_Float_xy[0] = last_Float_xy[0] + deltaXY_path1[0]*tempTimeDifferencePercent;
current_Float_xy[1] = last_Float_xy[1] + deltaXY_path1[1]*tempTimeDifferencePercent;
temp_canvas.drawLine(last_Float_xy[0],last_Float_xy[1],current_Float_xy[0],current_Float_xy[1],
strokePaint);
mPicture.endRecording();
mPicture.draw(temp_canvas);
postInvalidate();
}
}
调试日志显示
java.lang.UnsatisfiedLinkError: No implementation found for void
com.xxx.yyy.MyPicture.nativeEndRecording(long) (tried Java_com_xxx_yyy_MyPicture_nativeEndRecording and Java_com_xxx_yyy_MyPicture_nativeEndRecording__J)
at com.xxx.yyy.MyPicture.nativeEndRecording(Native Method)
at com.xxx.yyy.MyPicture.endRecording(MyPicture.java:140)
at com.xxx.yyy.MyCustomView.onDraw(MyCustomView.java:385)
at android.view.View.draw(View.java:20211)
at android.view.View.updateDisplayListIfDirty(View.java:19086)
at android.view.View.draw(View.java:19939)
at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
at android.view.View.updateDisplayListIfDirty(View.java:19077)
at android.view.View.draw(View.java:19939)
at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
at android.view.View.updateDisplayListIfDirty(View.java:19077)
at android.view.View.draw(View.java:19939)
at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
at android.view.View.updateDisplayListIfDirty(View.java:19077)
at android.view.View.draw(View.java:19939)
at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
at android.view.View.updateDisplayListIfDirty(View.java:19077)
at android.view.View.draw(View.java:19939)
at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
at android.view.View.updateDisplayListIfDirty(View.java:19077)
at android.view.View.draw(View.java:19939)
at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
at android.view.View.updateDisplayListIfDirty(View.java:19077)
at android.view.View.draw(View.java:19939)
at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
at android.view.View.draw(View.java:20214)
at com.android.internal.policy.DecorView.draw(DecorView.java:780)
at android.view.View.updateDisplayListIfDirty(View.java:19086)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:801)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:3327)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3124)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2493)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1468)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7208)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1004)
at android.view.Choreographer.doCallbacks(Choreographer.java:816)
at android.view.Choreographer.doFrame(Choreographer.java:751)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:990)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6692)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
我不知道什么“com.xxx.yyy.MyPicture.nativeEndRecording(long)(尝试过 Java_com_xxx_yyy_MyPicture_nativeEndRecording 和 Java_com_xxx_yyy_MyPicture_nativeEndRecording__J)”
但我认为当我使用不在原始图形包中的 MyPicture 时它找不到相应的本机代码。
问题(3):我想跳转到本机代码“nativeEndRecording”,看看我是否可以通过使用“Ctrl+left_mouse_click”在下面的列表中知道更具体的代码,但我在另一行跳转回相同的 MyPicture.java使用它。
这意味着我不知道如何检查、修改和重新创建自定义本机方法,并将方法注入 APP...
private static native long nativeConstructor(long nativeSrcOr0);
private static native long nativeCreateFromStream(InputStream stream, byte[] storage);
private static native int nativeGetWidth(long nativePicture);
private static native int nativeGetHeight(long nativePicture);
private static native long nativeBeginRecording(long nativeCanvas, int w, int h);
private static native void nativeEndRecording(long nativeCanvas);
private static native void nativeDraw(long nativeCanvas, long nativePicture);
private static native boolean nativeWriteToStream(long nativePicture,
OutputStream stream, byte[] storage);
private static native void nativeDestructor(long nativePicture);
我现在迷失了方向......我想做的只是保持以前的画布绘制并重复绘制更多短线(可能在 1 秒内逐渐绘制 60~166 行,长度为 30-100 像素,宽度为 30 像素)。
如果我只是重复 ondraw ~=166 次,APP 使用 83 Mb 图形内存。
当路径变得越来越长并且每次长度都略有增加时,它就像一个雪球和图形内存一样在最后几百毫秒内迅速恢复。