最近在Android 10 系统上发现SurfaceView 测试的时候奔溃了,10以前的系统测试都会奔溃,在Android 11之后的设备上是正常的。

上错误日志

Native 报错信息

signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4
Cause: null pointer dereferenceeax 00000000  ebx f017756c  ecx 00000001  edx 00017af6edi 00017af6  esi edbe9140ebp c4c67938  esp c4c67920  eip f0169a71backtrace:#00 pc 0000fa71  /system/lib/libutils.so (android::RefBase::incStrong(void const*) const+33) (BuildId: 288ba3aff5b46dbd7e74be954af88b83)#01 pc 00114620  /system/lib/libandroid_runtime.so (android::nativeDeferTransactionUntilSurface(_JNIEnv*, _jclass*, long long, long long, long long, long long)+96) (BuildId: 3643bee2c4fb7899d7781c565843060b)#02 pc 002a2325  /system/framework/x86/boot-framework.oat (art_jni_trampoline+213) (BuildId: 38176ebc9c3cce5f657a723b08d40d487952c484)#03 pc 0204d399  /memfd:/jit-cache (deleted) (android.view.SurfaceControl.access$2700+89)#04 pc 020421aa  /memfd:/jit-cache (deleted) (android.view.SurfaceControl$Transaction.deferTransactionUntilSurface+202)#05 pc 02036db1  /memfd:/jit-cache (deleted) (android.view.SurfaceView.applySurfaceTransforms+177)#06 pc 0204979f  /memfd:/jit-cache (deleted) (android.view.SurfaceView.setParentSpaceRectangle+95)#07 pc 020546cb  /memfd:/jit-cache (deleted) (android.view.SurfaceView.access$200+59)#08 pc 0204ae12  /memfd:/jit-cache (deleted) (android.view.SurfaceView$3.positionChanged+434)#09 pc 0203c004  /memfd:/jit-cache (deleted) (android.graphics.RenderNode$CompositePositionUpdateListener.positionChanged+148)

应用层log看到的错误信息

Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x10 in tid 6711 (hwuiTask0), pid 6669 (.crash)
Exception from repositionChildjava.lang.NullPointerException: mNativeObject is null. Have you called release() already?at android.view.SurfaceControl.checkNotReleased(SurfaceControl.java:945)at android.view.SurfaceControl.access$800(SurfaceControl.java:77)at android.view.SurfaceControl$Transaction.setPosition(SurfaceControl.java:2170)at android.view.SurfaceView.applySurfaceTransforms(SurfaceView.java:1025)at android.view.SurfaceView.setParentSpaceRectangle(SurfaceView.java:1038)at android.view.SurfaceView.access$200(SurfaceView.java:99)at android.view.SurfaceView$1.positionChanged(SurfaceView.java:1081)

根据报错的信息在网上查找到相关的一个google patch

commit   005c63e8c6e6e5b312dc9c4631c57fb12224df30    [log] [tgz]
author  Robert Carr <racarr@google.com>  Fri Sep 20 14:31:24 2019 -0700
committer   Robert Carr <racarr@google.com>  Fri Sep 20 14:48:40 2019 -0700
tree    939eaeca0159a44bca7b5abf44f41f5096c1fb90
parent  c48da419931a3a9272910f2631f815cecf05c9ba [diff]
SurfaceView: Destroy SurfaceControl from RenderThreadCurrently there is a race where the UI thread can destroy
the SurfaceControl (free the C++ object) while the RenderThread
still has pending operations on it. To fix have the positionLost callback handle the destruction.Bug: 139111930
Bug: 136808018
Test: go/wm-smoke
Change-Id: Id5225e1e47046d928f8298de38ff61662debe360
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 90e69f3..262b9e5 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -136,6 +136,7 @@@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)boolean mIsCreating = false;private volatile boolean mRtHandlingPositionUpdates = false;
+    private volatile boolean mRtReleaseSurfaces = false;private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener =this::updateSurface;
@@ -658,7 +659,14 @@}private void releaseSurfaces() {
+        mSurfaceAlpha = 1f;
+synchronized (mSurfaceControlLock) {
+            if (mRtHandlingPositionUpdates) {
+                mRtReleaseSurfaces = true;
+                return;
+            }
+if (mSurfaceControl != null) {mTmpTransaction.remove(mSurfaceControl);mSurfaceControl = null;
@@ -669,7 +677,6 @@}mTmpTransaction.apply();}
-        mSurfaceAlpha = 1f;}/** @hide */
@@ -1084,7 +1091,9 @@// the synchronization would violate the rule that RT must never block// on the UI thread which would open up potential deadlocks. The risk of// a single-frame desync is therefore preferable for now.
-            mRtHandlingPositionUpdates = true;
+            synchronized(mSurfaceControlLock) {
+                mRtHandlingPositionUpdates = true;
+            }if (mRTLastReportedPosition.left == left&& mRTLastReportedPosition.top == top&& mRTLastReportedPosition.right == right
@@ -1126,6 +1135,18 @@frameNumber);}mRtTransaction.hide(mSurfaceControl);
+
+            synchronized (mSurfaceControlLock) {
+                if (mRtReleaseSurfaces) {
+                    mRtReleaseSurfaces = false;
+                    mRtTransaction.remove(mSurfaceControl);
+                    mRtTransaction.remove(mBackgroundControl);
+                    mSurfaceControl = null;
+                    mBackgroundControl = null;
+                }
+                mRtHandlingPositionUpdates = false;
+            }
+mRtTransaction.apply();}};

更新后SurfaceView getViewRootImpl()会经常为空。找不到其他更新的patch。
因为在Android11 上测试是正常的,所以Android11 是解决了这个问题的,所以直接抄Android11 的SurfaceView的代码。因为Android11 更新了很多东西,所以挑相关的修改进行更新。

diff --git a/frameworks/base/core/java/android/view/SurfaceView.java b/frameworks/base/core/java/android/view/SurfaceView.java
index d11548d687..3d1a5a3549 100644
--- a/frameworks/base/core/java/android/view/SurfaceView.java
+++ b/frameworks/base/core/java/android/view/SurfaceView.java
@@ -118,8 +118,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbboolean mDrawFinished = false;final Rect mScreenRect = new Rect();
-    SurfaceSession mSurfaceSession;
-
+    private final SurfaceSession mSurfaceSession = new SurfaceSession();SurfaceControl mSurfaceControl;// In the case of format changes we switch out the surface in-place// we need to preserve the old one until the new one has drawn.
@@ -135,6 +134,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)boolean mIsCreating = false;private volatile boolean mRtHandlingPositionUpdates = false;
+    private volatile boolean mRtReleaseSurfaces = false;private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener =this::updateSurface;
@@ -428,9 +428,16 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb}private void performDrawFinished() {
+        if (mDeferredDestroySurfaceControl != null) {
+            synchronized (mSurfaceControlLock) {
+                mTmpTransaction.remove(mDeferredDestroySurfaceControl).apply();
+                mDeferredDestroySurfaceControl = null;
+            }
+        }if (mPendingReportDraws > 0) {mDrawFinished = true;if (mAttachedToWindow) {
+                mParent.requestTransparentRegion(SurfaceView.this);notifyDrawFinished();invalidate();}
@@ -658,7 +665,15 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb}private void releaseSurfaces() {
+        mSurfaceAlpha = 1f;
+synchronized (mSurfaceControlLock) {
+            mSurface.release();
+            if (mRtHandlingPositionUpdates) {
+                mRtReleaseSurfaces = true;
+                return;
+            }
+if (mSurfaceControl != null) {mTmpTransaction.remove(mSurfaceControl);mSurfaceControl = null;
@@ -669,7 +684,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb}mTmpTransaction.apply();}
-        mSurfaceAlpha = 1f;}/** @hide */
@@ -680,12 +694,21 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb}return;}
-        ViewRootImpl viewRoot = getViewRootImpl();
-        if (viewRoot == null || viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {
+        final ViewRootImpl viewRoot = getViewRootImpl();
+        if (viewRoot == null) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this)
+                        + " updateSurface: viewRoot null");
+            }
+            return;
+        }
+        if (viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {if (DEBUG) {Log.d(TAG, System.identityHashCode(this)+ " updateSurface: no valid surface");}
+            notifySurfaceDestroyed();
+            releaseSurfaces();return;}@@ -708,9 +731,14 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbfinal boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight;final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility;boolean redrawNeeded = false;
-
-        if (creating || formatChanged || sizeChanged || visibleChanged || (mUseAlpha
-                && alphaChanged) || windowVisibleChanged) {
+        getLocationInSurface(mLocation);
+        final boolean positionChanged = mWindowSpaceLeft != mLocation[0]
+            || mWindowSpaceTop != mLocation[1];
+        final boolean layoutSizeChanged = getWidth() != mScreenRect.width()
+            || getHeight() != mScreenRect.height();
+        if (creating || formatChanged || sizeChanged || visibleChanged ||
+                (mUseAlpha && alphaChanged) || windowVisibleChanged ||
+                positionChanged || layoutSizeChanged) {getLocationInWindow(mLocation);if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
@@ -744,7 +772,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbif (creating) {viewRoot.createBoundsSurface(mSubLayer);
-                    mSurfaceSession = new SurfaceSession();mDeferredDestroySurfaceControl = mSurfaceControl;updateOpaqueFlag();
@@ -853,28 +880,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbfinal boolean surfaceChanged = creating;if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) {mSurfaceCreated = false;
-                        if (mSurface.isValid()) {
-                            if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
-                                    + "visibleChanged -- surfaceDestroyed");
-                            callbacks = getSurfaceCallbacks();
-                            for (SurfaceHolder.Callback c : callbacks) {
-                                c.surfaceDestroyed(mSurfaceHolder);
-                            }
-                            // Since Android N the same surface may be reused and given to us
-                            // again by the system server at a later point. However
-                            // as we didn't do this in previous releases, clients weren't
-                            // necessarily required to clean up properly in
-                            // surfaceDestroyed. This leads to problems for example when
-                            // clients don't destroy their EGL context, and try
-                            // and create a new one on the same surface following reuse.
-                            // Since there is no valid use of the surface in-between
-                            // surfaceDestroyed and surfaceCreated, we force a disconnect,
-                            // so the next connect will always work if we end up reusing
-                            // the surface.
-                            if (mSurface.isValid()) {
-                                mSurface.forceScopedDisconnect();
-                            }
-                        }
+                        notifySurfaceDestroyed();}if (creating) {
@@ -933,7 +939,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb} finally {mIsCreating = false;if (mSurfaceControl != null && !mSurfaceCreated) {
-                        mSurface.release();releaseSurfaces();}}
@@ -944,48 +949,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbTAG, "Layout: x=" + mScreenRect.left + " y=" + mScreenRect.top+ " w=" + mScreenRect.width() + " h=" + mScreenRect.height()+ ", frame=" + mSurfaceFrame);
-        } else {
-            // Calculate the window position in case RT loses the window
-            // and we need to fallback to a UI-thread driven position update
-            getLocationInSurface(mLocation);
-            final boolean positionChanged = mWindowSpaceLeft != mLocation[0]
-                    || mWindowSpaceTop != mLocation[1];
-            final boolean layoutSizeChanged = getWidth() != mScreenRect.width()
-                    || getHeight() != mScreenRect.height();
-            if (positionChanged || layoutSizeChanged) { // Only the position has changed
-                mWindowSpaceLeft = mLocation[0];
-                mWindowSpaceTop = mLocation[1];
-                // For our size changed check, we keep mScreenRect.width() and mScreenRect.height()
-                // in view local space.
-                mLocation[0] = getWidth();
-                mLocation[1] = getHeight();
-
-                mScreenRect.set(mWindowSpaceLeft, mWindowSpaceTop,
-                        mWindowSpaceLeft + mLocation[0], mWindowSpaceTop + mLocation[1]);
-
-                if (translator != null) {
-                    translator.translateRectInAppWindowToScreen(mScreenRect);
-                }
-
-                if (mSurfaceControl == null) {
-                    return;
-                }
-
-                if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) {
-                    try {
-                        if (DEBUG_POSITION) {
-                            Log.d(TAG, String.format("%d updateSurfacePosition UI, "
-                                            + "position = [%d, %d, %d, %d]",
-                                    System.identityHashCode(this),
-                                    mScreenRect.left, mScreenRect.top,
-                                    mScreenRect.right, mScreenRect.bottom));
-                        }
-                        setParentSpaceRectangle(mScreenRect, -1);
-                    } catch (Exception ex) {
-                        Log.e(TAG, "Exception configuring surface", ex);
-                    }
-                }
-            }}}@@ -994,12 +957,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbLog.i(TAG, System.identityHashCode(this) + " "+ "finishedDrawing");}
-
-        if (mDeferredDestroySurfaceControl != null) {
-            mTmpTransaction.remove(mDeferredDestroySurfaceControl).apply();
-            mDeferredDestroySurfaceControl = null;
-        }
-runOnUiThread(this::performDrawFinished);}@@ -1015,9 +972,8 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb}private void applySurfaceTransforms(SurfaceControl surface, Rect position, long frameNumber) {
-        if (frameNumber > 0) {
-            final ViewRootImpl viewRoot = getViewRootImpl();
-
+        final ViewRootImpl viewRoot = getViewRootImpl();
+        if (frameNumber > 0 && viewRoot != null ) {mRtTransaction.deferTransactionUntilSurface(surface, viewRoot.mSurface,frameNumber);}
@@ -1036,10 +992,10 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbfinal ViewRootImpl viewRoot = getViewRootImpl();applySurfaceTransforms(mSurfaceControl, position, frameNumber);
-
-        applyChildSurfaceTransaction_renderWorker(mRtTransaction, viewRoot.mSurface,
+        if (frameNumber > 0 && viewRoot != null ) {
+            applyChildSurfaceTransaction_renderWorker(mRtTransaction, viewRoot.mSurface,frameNumber);
-
+        }mRtTransaction.apply();}@@ -1062,7 +1018,9 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb// the synchronization would violate the rule that RT must never block// on the UI thread which would open up potential deadlocks. The risk of// a single-frame desync is therefore preferable for now.
-            mRtHandlingPositionUpdates = true;
+            synchronized(mSurfaceControlLock) {
+                mRtHandlingPositionUpdates = true;
+            }if (mRTLastReportedPosition.left == left&& mRTLastReportedPosition.top == top&& mRTLastReportedPosition.right == right
@@ -1096,14 +1054,27 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbif (mSurfaceControl == null) {return;}
+            final ViewRootImpl viewRoot = getViewRootImpl();-            if (frameNumber > 0) {
-                final ViewRootImpl viewRoot = getViewRootImpl();-                mRtTransaction.deferTransactionUntilSurface(mSurfaceControl, viewRoot.mSurface,
-                        frameNumber);
+            synchronized (mSurfaceControlLock) {
+                if (frameNumber > 0 && viewRoot != null) {
+                    if (viewRoot.mSurface.isValid()) {
+                        mRtTransaction.deferTransactionUntilSurface(mSurfaceControl, viewRoot.mSurface,
+                                frameNumber);
+                                       }
+                }
+                mRtTransaction.hide(mSurfaceControl);
+                if (mRtReleaseSurfaces) {
+                    mRtReleaseSurfaces = false;
+                    mRtTransaction.remove(mSurfaceControl);
+                    mRtTransaction.remove(mBackgroundControl);
+                    mSurfaceControl = null;
+                    mBackgroundControl = null;
+                }
+                mRtHandlingPositionUpdates = false;}
-            mRtTransaction.hide(mSurfaceControl);
+mRtTransaction.apply();}};
@@ -1348,4 +1319,29 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbpublic SurfaceControl getSurfaceControl() {return mSurfaceControl;}
+
+    private void notifySurfaceDestroyed() {
+        if (mSurface.isValid()) {
+            if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+                    + "surfaceDestroyed");
+            SurfaceHolder.Callback[] callbacks = getSurfaceCallbacks();
+            for (SurfaceHolder.Callback c : callbacks) {
+                c.surfaceDestroyed(mSurfaceHolder);
+            }
+            // Since Android N the same surface may be reused and given to us
+            // again by the system server at a later point. However
+            // as we didn't do this in previous releases, clients weren't
+            // necessarily required to clean up properly in
+            // surfaceDestroyed. This leads to problems for example when
+            // clients don't destroy their EGL context, and try
+            // and create a new one on the same surface following reuse.
+            // Since there is no valid use of the surface in-between
+            // surfaceDestroyed and surfaceCreated, we force a disconnect,
+            // so the next connect will always work if we end up reusing
+            // the surface.
+            if (mSurface.isValid()) {
+                mSurface.forceScopedDisconnect();
+            }
+        }
+    }}

经过修改后,测试是正常了,应用不会奔溃,就是时不时冒出一个Error的log信息
E/Layer: [SurfaceView - com.crash/com.crash.MainActivity#3] No local sync point found

查看Layer.cpp 遇到这种异常的时候是跳过逻辑的,所以就不管了,目前还不清楚这样改有没有其他什么问题。

 741 bool Layer::applyPendingStates(State* stateToCommit) {742     bool stateUpdateAvailable = false;743     while (!mPendingStates.empty()) {744         if (mPendingStates[0].barrierLayer_legacy != nullptr) {745             if (mRemoteSyncPoints.empty()) {746                 // If we don't have a sync point for this, apply it anyway. It747                 // will be visually wrong, but it should keep us from getting748                 // into too much trouble.749                 ALOGE("[%s] No local sync point found", mName.string());750                 popPendingState(stateToCommit);751                 stateUpdateAvailable = true;752                 continue;753             }754755             if (mRemoteSyncPoints.front()->getFrameNumber() !=756                 mPendingStates[0].frameNumber_legacy) {757                 ALOGE("[%s] Unexpected sync point frame number found", mName.string());758759                 // Signal our end of the sync point and then dispose of it760                 mRemoteSyncPoints.front()->setTransactionApplied();761                 mRemoteSyncPoints.pop_front();762                 continue;763             }764765             if (mRemoteSyncPoints.front()->frameIsAvailable()) {766                 ATRACE_NAME("frameIsAvailable");767                 // Apply the state update768                 popPendingState(stateToCommit);769                 stateUpdateAvailable = true;770771                 // Signal our end of the sync point and then dispose of it772                 mRemoteSyncPoints.front()->setTransactionApplied();773                 mRemoteSyncPoints.pop_front();774             } else {775                 ATRACE_NAME("!frameIsAvailable");776                 break;777             }778         } else {779             popPendingState(stateToCommit);780             stateUpdateAvailable = true;781         }782     }783784     // If we still have pending updates, wake SurfaceFlinger back up and point785     // it at this layer so we can process them786     if (!mPendingStates.empty()) {787         setTransactionFlags(eTransactionNeeded);788         mFlinger->setTransactionFlags(eTraversalNeeded);789     }790791     mCurrentState.modified = false;792     return stateUpdateAvailable;793 }

Android 10 SurfaceView 奔溃报错signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4相关推荐

  1. cn.sample.mnn.detect A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid

    mnn报错: cn.sample.mnn.detect A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 ...

  2. 游戏测试问题之:Caused by: java.lang.Error: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000004

    公司开发的小游戏在进行 Monkey 测试时在个别机型一直遇到相同的几个问题,特此记录一下 错误日志如下: Caused by: java.lang.Error: signal 11 (SIGSEGV ...

  3. A/libc:fatal signal 11(SIGSEGV).code 1, fault addr 0x0 in tid 26488 (VideoEncoder)

    在调试Camera模块:发现相同的代码在厂家提供的环境里边编译.就是ok的,在我们的源码树中编译,将HAL库推进去后.就会signal 11退出. 一.现象 1 F/libc ( 4250): Fat ...

  4. Fatal signal 11 (SIGSEGV), code 1, fault addr 0x10457e30d996b in tid 5676 (ndroid.settings)

    FROM:http://blogold.chinaunix.net/u3/104564/showart_2091186.html 一.安装交叉编译器  1)交叉编译器使用CodeSourcery提供的 ...

  5. signal 11 (SIGSEGV), code 2 (SEGV_ACCERR)的原因和解决办法

    码字不易,转载请注明出处喔 https://blog.csdn.net/newchenxf/article/details/121537539 1 结论 可能你打开这篇文章,是在某个加班的深夜,时间真 ...

  6. Android JNI 报错(signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr )

    目前看是线程调用问题引起的 , 错误Log如下: F DEBUG : uid: 1000 F DEBUG : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault ...

  7. Android NDK thread 回收crash, signal 4 (SIGILL), code 1 (ILL_ILLOPC) , fault addr 地址

    Android NDK thread 回收crash, signal 4 (SIGILL), code 1 (ILL_ILLOPC) , fault addr 地址 在NDK c++ 使用pthrea ...

  8. JNI中Fatal signal 11 (SIGSEGV), code 1的错误.

    这个错,搞了一天才搞定.还是自己对jni不熟. com.viking.myapplication A/libc: Fatal signal 11 (SIGSEGV), code 1, fault ad ...

  9. 【我的C/C++语言学习进阶之旅】NDK开发之解决错误:signal 5 (SIGTRAP), code 1 (TRAP_BRKPT), fault addr 0xXXX

    一.错误描述 今天在使用C++实现一个OpenGL特效的时候,运行出错,如下所示: 错误描述为: signal 5 (SIGTRAP), code 1 (TRAP_BRKPT), fault addr ...

最新文章

  1. Java源码详解二:HashMap源码分析--openjdk java 11源码
  2. cm 怎么限制hue数据下载_0724-6.2.0-CM接管rpm方式安装的无CM的CDH集群-2
  3. 对 Jquery 表单插件 Form.js 2.12 的调整
  4. ios 防止按钮快速点击造成多次响应的避免方法。
  5. 【Error】IDEA报错:org.jetbrains.jps.builders.java.dependencyView.TypeRepr$PrimitiveType cannot be cast t
  6. 米的建站日记(2014年12月15日)
  7. Shiro过滤器配置(ShiroFilterFactoryBean)
  8. mysql之select+五种子句的理解
  9. 东京疫情数据开源当日斩获2k+ star,GitHub疫情项目源源不断
  10. 使用Jackson解析JSON
  11. params.c:Parameter() - Ignoring badly formed line in configuration file: ignore errors 解决方法
  12. Linux为硬盘重建MBR,linux重建mbr
  13. C语言 switch语句来调用函数
  14. Loongson2f_灵珑9S2A_debian5(lenny)更改国内archive软件源并使用源码编译安装bochs-2.6.9
  15. 解析button和input type=button 的区别
  16. 随机的Lazy-Greedy:lazier than lazy greedy
  17. 微信 8.0 「裂开」「炸弹」的特效代码来了
  18. 优酷路由宝增加php,优酷路由宝刷入breed教程
  19. 固高Otostudio软件使用基础知识
  20. css3摇骰子,css3实现掷骰子(无图)

热门文章

  1. DVWA V1.9:Reflected Cross Site Scripting(存储型XSS)
  2. ps2021直装版|ps2021中文直装版 v22.0.0.35附安装教程
  3. 微信终于出新功能了:自动登录该设备
  4. 如何正确修改标题,如何修改标题不会被降权?
  5. win7系统的两种硬盘格式mbr和gpt怎么选择?
  6. linux ls 目录颜色,改变ls 中目录颜色的方法
  7. 宝塔linux升级,宝塔linux面板去除后台强制更新
  8. Ubuntu18.04更换开机登录界面壁纸
  9. 对于我们大冒险游戏的评论回复
  10. iPhone的解锁、越狱、激活、固件等等是什么意思,有什么分别?