基本信息介绍:
引擎框架: Quick-Cocos2dx-Community-3.6
测试机型: 魅族MX5
问题简介:
有拖动效果的物件,在拖动的工程中,手指不放,同时点击home键退到后台。
再返回应用,发现onTouchEnded里头有添加精灵的话,会变黑色。
问题排查:
首先排查生命周期。因为属于点击会被打断,会执行onTouchCancelled。所以真机调试发现先执行了onPause事件,再执行了onTouchCancelled。
这2个事件有一定的间隔时间,导致图片没加载进内存,但是缓存存在了。
问题思考:
1.能否调整生命周期
把onPause()打开,会有其他问题。
2.思考把onTouchCancel调用提前
1 /**************************************************************************** 2 Copyright (c) 2010-2011 cocos2d-x.org 3 4 http://www.cocos2d-x.org 5 6 Permission is hereby granted, free of charge, to any person obtaining a copy 7 of this software and associated documentation files (the "Software"), to deal 8 in the Software without restriction, including without limitation the rights 9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 copies of the Software, and to permit persons to whom the Software is 11 furnished to do so, subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be included in 14 all copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 THE SOFTWARE. 23 ****************************************************************************/ 24 package org.cocos2dx.lib; 25 26 import android.content.Context; 27 import android.opengl.GLSurfaceView; 28 import android.os.Handler; 29 import android.os.Message; 30 import android.util.AttributeSet; 31 import android.util.Log; 32 import android.view.KeyEvent; 33 import android.view.MotionEvent; 34 import android.view.inputmethod.InputMethodManager; 35 36 import com.babybus.app.App; 37 import com.babybus.utils.GameCallbackManager; 38 import com.babybus.utils.LogUtil; 39 40 public class Cocos2dxGLSurfaceView extends GLSurfaceView { 41 // =========================================================== 42 // Constants 43 // =========================================================== 44 45 private static final String TAG = Cocos2dxGLSurfaceView.class.getSimpleName(); 46 47 private final static int HANDLER_OPEN_IME_KEYBOARD = 2; 48 private final static int HANDLER_CLOSE_IME_KEYBOARD = 3; 49 50 // =========================================================== 51 // Fields 52 // =========================================================== 53 54 // Static handler -> Potential leak! 55 private static Handler sHandler; 56 57 private static Cocos2dxGLSurfaceView mCocos2dxGLSurfaceView; 58 private static Cocos2dxTextInputWraper sCocos2dxTextInputWraper; 59 60 private Cocos2dxRenderer mCocos2dxRenderer; 61 private Cocos2dxEditText mCocos2dxEditText; 62 63 // 记录当前点击事件的值 64 private int[] touchIds; 65 private float[] touchXs; 66 private float[] touchYs;
67 // =========================================================== 68 // Constructors 69 // =========================================================== 70 71 public Cocos2dxGLSurfaceView(final Context context) { 72 super(context); 73 74 this.initView(); 75 } 76 77 public Cocos2dxGLSurfaceView(final Context context, final AttributeSet attrs) { 78 super(context, attrs); 79 80 this.initView(); 81 } 82 83 protected void initView() { 84 this.setEGLContextClientVersion(2); 85 this.setFocusableInTouchMode(true); 86 87 Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView = this; 88 Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper = new Cocos2dxTextInputWraper(this); 89 90 Cocos2dxGLSurfaceView.sHandler = new Handler() { 91 @Override 92 public void handleMessage(final Message msg) { 93 switch (msg.what) { 94 case HANDLER_OPEN_IME_KEYBOARD: 95 if (null != Cocos2dxGLSurfaceView.this.mCocos2dxEditText && Cocos2dxGLSurfaceView.this.mCocos2dxEditText.requestFocus()) { 96 Cocos2dxGLSurfaceView.this.mCocos2dxEditText.removeTextChangedListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper); 97 Cocos2dxGLSurfaceView.this.mCocos2dxEditText.setText(""); 98 final String text = (String) msg.obj; 99 Cocos2dxGLSurfaceView.this.mCocos2dxEditText.append(text); 100 Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper.setOriginText(text); 101 Cocos2dxGLSurfaceView.this.mCocos2dxEditText.addTextChangedListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper); 102 final InputMethodManager imm = (InputMethodManager) Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 103 imm.showSoftInput(Cocos2dxGLSurfaceView.this.mCocos2dxEditText, 0); 104 Log.d("GLSurfaceView", "showSoftInput"); 105 } 106 break; 107 108 case HANDLER_CLOSE_IME_KEYBOARD: 109 if (null != Cocos2dxGLSurfaceView.this.mCocos2dxEditText) { 110 Cocos2dxGLSurfaceView.this.mCocos2dxEditText.removeTextChangedListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper); 111 final InputMethodManager imm = (InputMethodManager) Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 112 imm.hideSoftInputFromWindow(Cocos2dxGLSurfaceView.this.mCocos2dxEditText.getWindowToken(), 0); 113 Cocos2dxGLSurfaceView.this.requestFocus(); 114 Log.d("GLSurfaceView", "HideSoftInput"); 115 } 116 break; 117 } 118 } 119 }; 120 } 121 122 // =========================================================== 123 // Getter & Setter 124 // =========================================================== 125 126 127 public static Cocos2dxGLSurfaceView getInstance() { 128 return mCocos2dxGLSurfaceView; 129 } 130 131 public static void queueAccelerometer(final float x, final float y, final float z, final long timestamp) { 132 mCocos2dxGLSurfaceView.queueEvent(new Runnable() { 133 @Override 134 public void run() { 135 Cocos2dxAccelerometer.onSensorChanged(x, y, z, timestamp); 136 } 137 }); 138 } 139 140 public void setCocos2dxRenderer(final Cocos2dxRenderer renderer) { 141 this.mCocos2dxRenderer = renderer; 142 this.setRenderer(this.mCocos2dxRenderer); 143 } 144 145 private String getContentText() { 146 return this.mCocos2dxRenderer.getContentText(); 147 } 148 149 public Cocos2dxEditText getCocos2dxEditText() { 150 return this.mCocos2dxEditText; 151 } 152 153 public void setCocos2dxEditText(final Cocos2dxEditText pCocos2dxEditText) { 154 this.mCocos2dxEditText = pCocos2dxEditText; 155 if (null != this.mCocos2dxEditText && null != Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper) { 156 this.mCocos2dxEditText.setOnEditorActionListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper); 157 this.mCocos2dxEditText.setCocos2dxGLSurfaceView(this); 158 this.requestFocus(); 159 } 160 } 161 162 // =========================================================== 163 // Methods for/from SuperClass/Interfaces 164 // =========================================================== 165 166 @Override 167 public void onResume() { 168 this.queueEvent(new Runnable() { 169 @Override 170 public void run() { 171 Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleOnResume(); 172 } 173 }); 174 175 this.setRenderMode(RENDERMODE_CONTINUOUSLY); 176 super.onResume(); 177 } 178 179 @Override 180 public void onPause() { 181 this.queueEvent(new Runnable() { 182 @Override 183 public void run() { 184 Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleOnPause(); 185 } 186 }); 187 this.setRenderMode(RENDERMODE_WHEN_DIRTY); 188 if(touchIds != null){ 189 this.queueEvent(new Runnable() { 190 @Override 191 public void run() { 192 Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionCancel(touchIds, touchXs, touchYs); 193 } 194 }); 195 } 196 // super.onPause(); 197 } 198 199 @Override 200 public boolean onTouchEvent(final MotionEvent pMotionEvent) { 201 202 if (App.get().isLockGameTouch){ 203 return false; 204 } 205 // these data are used in ACTION_MOVE and ACTION_CANCEL 206 final int pointerNumber = pMotionEvent.getPointerCount(); 207 final int[] ids = new int[pointerNumber]; 208 final float[] xs = new float[pointerNumber]; 209 final float[] ys = new float[pointerNumber]; 210 211 for (int i = 0; i < pointerNumber; i++) { 212 ids[i] = pMotionEvent.getPointerId(i); 213 xs[i] = pMotionEvent.getX(i); 214 ys[i] = pMotionEvent.getY(i); 215 } 216 217 switch (pMotionEvent.getAction() & MotionEvent.ACTION_MASK) { 218 case MotionEvent.ACTION_POINTER_DOWN: 219 final int indexPointerDown = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 220 final int idPointerDown = pMotionEvent.getPointerId(indexPointerDown); 221 final float xPointerDown = pMotionEvent.getX(indexPointerDown); 222 final float yPointerDown = pMotionEvent.getY(indexPointerDown); 223 224 touchIds = ids; 225 touchXs = xs; 226 touchYs = ys; 227 228 this.queueEvent(new Runnable() { 229 @Override 230 public void run() { 231 Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown(idPointerDown, xPointerDown, yPointerDown); 232 } 233 }); 234 break; 235 236 case MotionEvent.ACTION_DOWN: 237 // there are only one finger on the screen 238 final int idDown = pMotionEvent.getPointerId(0); 239 final float xDown = xs[0]; 240 final float yDown = ys[0]; 241 242 touchIds = ids; 243 touchXs = xs; 244 touchYs = ys; 245 246 this.queueEvent(new Runnable() { 247 @Override 248 public void run() { 249 Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown(idDown, xDown, yDown); 250 } 251 }); 252 break; 253 254 case MotionEvent.ACTION_MOVE: 255 256 touchIds = ids; 257 touchXs = xs; 258 touchYs = ys; 259 260 this.queueEvent(new Runnable() { 261 @Override 262 public void run() { 263 Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionMove(ids, xs, ys); 264 } 265 }); 266 break; 267 268 case MotionEvent.ACTION_POINTER_UP: 269 final int indexPointUp = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 270 final int idPointerUp = pMotionEvent.getPointerId(indexPointUp); 271 final float xPointerUp = pMotionEvent.getX(indexPointUp); 272 final float yPointerUp = pMotionEvent.getY(indexPointUp); 273 274 touchIds = null; 275 touchXs = null; 276 touchYs = null; 277 this.queueEvent(new Runnable() { 278 @Override 279 public void run() { 280 Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionUp(idPointerUp, xPointerUp, yPointerUp); 281 } 282 }); 283 break; 284 285 case MotionEvent.ACTION_UP: 286 // there are only one finger on the screen 287 final int idUp = pMotionEvent.getPointerId(0); 288 final float xUp = xs[0]; 289 final float yUp = ys[0]; 290 touchIds = null; 291 touchXs = null; 292 touchYs = null; 293 this.queueEvent(new Runnable() { 294 @Override 295 public void run() { 296 Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionUp(idUp, xUp, yUp); 297 } 298 }); 299 break; 300 301 case MotionEvent.ACTION_CANCEL: 302 touchIds = null; 303 touchXs = null; 304 touchYs = null; 305 this.queueEvent(new Runnable() { 306 @Override 307 public void run() { 308 // Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionCancel(ids, xs, ys); 309 } 310 }); 311 break; 312 } 313 314 /* 315 if (BuildConfig.DEBUG) { 316 Cocos2dxGLSurfaceView.dumpMotionEvent(pMotionEvent); 317 } 318 */ 319 return true; 320 } 321 322 /* 323 * This function is called before Cocos2dxRenderer.nativeInit(), so the 324 * width and height is correct. 325 */ 326 @Override 327 protected void onSizeChanged(final int pNewSurfaceWidth, final int pNewSurfaceHeight, final int pOldSurfaceWidth, final int pOldSurfaceHeight) { 328 if(!this.isInEditMode()) { 329 this.mCocos2dxRenderer.setScreenWidthAndHeight(pNewSurfaceWidth, pNewSurfaceHeight); 330 String screenSize = ""+pNewSurfaceWidth+"|"+pNewSurfaceHeight; 331 LogUtil.t("change===test2"); 332 GameCallbackManager.gameCallback("FOLD_SCREEN_CHANGE", "NEW_SCREEN_SIZE", screenSize); 333 } 334 } 335 336 @Override 337 public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) { 338 switch (pKeyCode) { 339 case KeyEvent.KEYCODE_BACK: 340 Cocos2dxVideoHelper.mVideoHandler.sendEmptyMessage(Cocos2dxVideoHelper.KeyEventBack); 341 case KeyEvent.KEYCODE_MENU: 342 case KeyEvent.KEYCODE_DPAD_LEFT: 343 case KeyEvent.KEYCODE_DPAD_RIGHT: 344 case KeyEvent.KEYCODE_DPAD_UP: 345 case KeyEvent.KEYCODE_DPAD_DOWN: 346 case KeyEvent.KEYCODE_ENTER: 347 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 348 case KeyEvent.KEYCODE_DPAD_CENTER: 349 this.queueEvent(new Runnable() { 350 @Override 351 public void run() { 352 Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleKeyDown(pKeyCode); 353 } 354 }); 355 return true; 356 default: 357 return super.onKeyDown(pKeyCode, pKeyEvent); 358 } 359 } 360 361 // =========================================================== 362 // Methods 363 // =========================================================== 364 365 // =========================================================== 366 // Inner and Anonymous Classes 367 // =========================================================== 368 369 public static void openIMEKeyboard() { 370 final Message msg = new Message(); 371 msg.what = Cocos2dxGLSurfaceView.HANDLER_OPEN_IME_KEYBOARD; 372 msg.obj = Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView.getContentText(); 373 Cocos2dxGLSurfaceView.sHandler.sendMessage(msg); 374 } 375 376 public static void closeIMEKeyboard() { 377 final Message msg = new Message(); 378 msg.what = Cocos2dxGLSurfaceView.HANDLER_CLOSE_IME_KEYBOARD; 379 Cocos2dxGLSurfaceView.sHandler.sendMessage(msg); 380 } 381 382 public void insertText(final String pText) { 383 this.queueEvent(new Runnable() { 384 @Override 385 public void run() { 386 Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleInsertText(pText); 387 } 388 }); 389 } 390 391 public void deleteBackward() { 392 this.queueEvent(new Runnable() { 393 @Override 394 public void run() { 395 Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleDeleteBackward(); 396 } 397 }); 398 } 399 400 private static void dumpMotionEvent(final MotionEvent event) { 401 final String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" }; 402 final StringBuilder sb = new StringBuilder(); 403 final int action = event.getAction(); 404 final int actionCode = action & MotionEvent.ACTION_MASK; 405 sb.append("event ACTION_").append(names[actionCode]); 406 if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP) { 407 sb.append("(pid ").append(action >> MotionEvent.ACTION_POINTER_INDEX_SHIFT); 408 sb.append(")"); 409 } 410 sb.append("["); 411 for (int i = 0; i < event.getPointerCount(); i++) { 412 sb.append("#").append(i); 413 sb.append("(pid ").append(event.getPointerId(i)); 414 sb.append(")=").append((int) event.getX(i)); 415 sb.append(",").append((int) event.getY(i)); 416 if (i + 1 < event.getPointerCount()) { 417 sb.append(";"); 418 } 419 } 420 sb.append("]"); 421 Log.d(Cocos2dxGLSurfaceView.TAG, sb.toString()); 422 } 423 }
经过试验,下面一种完美解决问题。