如何将SurfaceView中的Canvas保存为Bitmap?

普通的Canvas可以通过下面的方法来将绘制内容保存为Bitmap

 Bitmap bitmap = new Bitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawXXX

但问题是,SurfaceView中Canvas是通过lockCanvas获取的,请问这种情况下,该如何将Canvas保存为Bitmap呢??

1个回答

你可以自己写个SurfaceView子类 拦截一下onDraw

如果你是用来摄像头抓图的话直接Camera.setPreviewCallback 能获取图片流

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
Android 如何获取surfaceview上的图片

Android 如何获取surfaceview上的图片 Canvas canvas=holder.lockCanvas(); bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.test); canvas.drawBitmap(bitmap, 0, 0, null); holder.unlockCanvasAndPost(canvas); 然后我会再锁一个区域,将surfaceview上的图片更新,之后想保存更新后的整张surfaceview上的图片,这应该怎么写

如何在自定义surfaceView 绘图面板上放置图片 或者bitmap

我在涂鸦面板上绘制图片以bitmap形式保存涂鸦 在转变成byte的形式存入数据库请问如何把数据库中的涂鸦再打开显示到绘图面板上 期待各位大神的回复

android canvas(bitmap)失败

目前使用canvas在surfaceview上画路径 需要对路径进行缩放处理 所以想把canvas画的图放在bitmap上进行缩放处理 但是 使用canvas(bitmap)后,画出来的点,并没有显示在bitmap上是什么原因呀

Android 使用Canvas保存后一片黑色的

![![图片说明](https://img-ask.csdn.net/upload/201507/29/1438145624_991069.png) 调用方法 ,,在本地能看到图片 但是全是黑色的 图片说明](https://img-ask.csdn.net/upload/201507/29/1438145669_593845.png)

surfaceCreated() 在SurfaceView被创建后无法被调用

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{ private Context mainActivity; private Paint paint; public MySurfaceView(Context context) { super(context); mainActivity=context; //getHolder().setFixedSize(300,300); getHolder().addCallback(this); paint=new Paint(); paint.setAntiAlias(true); } @Override protected void onDraw(Canvas canvas) { Bitmap bitmap= BitmapFactory.decodeResource(mainActivity.getResources(), R.drawable.score_128x128); canvas.drawBitmap(bitmap, 20, 130, paint); Matrix m1=new Matrix(); m1.setTranslate(360, 80); Matrix m2=new Matrix(); m2.setRotate(45); Matrix mix=new Matrix(); mix.setConcat(m1,m2); paint.setAlpha(128); canvas.drawBitmap(bitmap,100,50,paint); } @Override public void surfaceCreated(SurfaceHolder holder) { Toast.makeText(mainActivity,"exception",Toast.LENGTH_SHORT); Canvas canvas=holder.lockCanvas(); try { synchronized (holder){ onDraw(canvas); } }catch (Exception e){ Toast.makeText(mainActivity,"exception",Toast.LENGTH_SHORT); }finally { holder.unlockCanvasAndPost(canvas); } } Activity里new一个MySurfaceView public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MySurfaceView mySurfaceView=new MySurfaceView(MainActivity.this); setContentView(R.layout.activity_main); }

SurfaceView 中 触发OnTouch 事件时图片绘制异常,怎么解决

1. * 1. public class PaintGameView extends SurfaceView implements Runnable, SurfaceHolder.Callback, View.OnTouchListener { Config config = new Config(); private SurfaceHolder holder; private Bitmap lsecCache; private ArrayList<GameViews> gameImages = new ArrayList<>(); private ArrayList<Bullet> bullets = new ArrayList<>(); private ArrayList<Bitmap> enemys = new ArrayList<>(); private Boolean runState = false; private Context context; private Hero selectedPlane; public PaintGameView(Context context, Config config){ super(context); this.context = context; getHolder().addCallback(this); setOnTouchListener(this); } private void init(){ new importInit(config); enemys = importInit.getsBitmap("enemy"); gameImages.add(new BackgroundImage(config)); gameImages.add(new Enemy(config, enemys)); gameImages.add(new Hero(config)); lsecCache = Bitmap.createBitmap(config.getWidth(), config.getHeight(), Bitmap.Config.ARGB_8888); } @Override public void run() { Paint p = new Paint(); int time = 0; int timeBullet = 0; Canvas canvas; try { while (runState){ //描绘子弹部分 if(selectedPlane != null){ if(timeBullet++ == 4){ bullets.add(new Bullet(config, selectedPlane, bullets)); timeBullet = 0; } } canvas = new Canvas(lsecCache); //默认描绘 for(GameViews gameImage : (ArrayList<GameViews>)gameImages.clone()){ if(gameImage instanceof Enemy){ Enemy enemy = (Enemy) gameImage; if(!enemy.flag){ enemy.attacked(bullets); }else { if(enemy.index++ > 3){ gameImages.remove(gameImage); continue; } } } canvas.drawBitmap(gameImage.getBitmap(), gameImage.getX(), gameImage.getY(), p); } for(GameViews gameImage : (ArrayList<GameViews>)bullets.clone()){ canvas.drawBitmap(gameImage.getBitmap(), gameImage.getX(), gameImage.getY(), p); } if(time++ == 50){ gameImages.add(new Enemy(config, enemys)); time = 0; } Canvas c = holder.lockCanvas(); // c.drawBitmap(bg , 0, 0, p); c.drawBitmap(lsecCache, 0, 0, p); holder.unlockCanvasAndPost(c); Thread.sleep(10); } }catch (Exception e){ Log.e("APP.TAG","异常",e); } } @Override public void surfaceCreated(SurfaceHolder holder) { config.setContext(context); config.setSpeed(4); config.setGameViewses(gameImages); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { runState = true; //获取屏幕尺寸 config.setWidth(width); config.setHeight(height); init(); this.holder = holder; new Thread(this).start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { runState = false; } @Override public boolean onTouch(View v, MotionEvent event){ if(event.getAction() == MotionEvent.ACTION_DOWN){ for(GameViews gameView : gameImages) { if(gameView instanceof Hero){ if(gameView.selected(event.getX(), event.getY())){ // Log.i("APP.TAG", "我被选中!"); selectedPlane = (Hero) gameView; }else { selectedPlane = null; } break; } } }else if(event.getAction() == MotionEvent.ACTION_MOVE){ if(selectedPlane != null){ selectedPlane.setX((int) event.getX() - selectedPlane.getBitmap().getWidth()/2); selectedPlane.setY((int) event.getY() - selectedPlane.getBitmap().getHeight()/2); } }else if(event.getAction() == MotionEvent.ACTION_UP){ selectedPlane = null; } return true; } } 发射子弹时,敌机加速了,是onTouch引发的,查过不是参数配置引起的,求解决

android,在一个Surfaceview上画了一个矩形,怎样再在这个矩形上画曲线?

要求:只画出这条曲线,曲线之外的部分不能覆盖原来的图形。如果先框出一个小矩形区域,然后再在这个区域里画曲线,结果会是整个小矩形区域都会覆盖掉原来的图形。

android 清理画布canvas后 背景变黑色 可以设置颜色 但不能变得透明了 怎么才能变透明?

我分别用下面两个方法清理画布 1、 canvas.drawColor(colorAlpha, PorterDuff.Mode.CLEAR); 2、 Paint p = new Paint(); // //清屏 // p.setXfermode(new PorterDuffXfermode(Mode.CLEAR)); // canvas.drawPaint(p); // p.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 背景变成黑色 怎么回到透明

SurfaceView缩放、拖拽、涂鸦功能,进行坐标换算

改写了一个surfaceView,之前有缩放、拖拽功能,根据我的应用需求,我需要加上涂鸦功能, 在这个过程中,我可以再上面画矩形。画矩形没有问题,但是在画好图形进行缩放的时候,画的矩形来回抖动,不能固定,在坐标换算的时候出问题了,一直找不到问题在哪里,求高人指点。 这里坐标换算,是换算成相对于bitmap的坐标,因为bitmap是等比例缩放的,不是铺满整个surfaceview的 调用源码: ``` public MySurfaceView3 msvZoom; Bitmap bm = BitmapFactory.decodeFile(imgPath); msvZoom.setBitmap(bm); ``` 自定义SurfaceView代码 ``` import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PointF; import android.graphics.Rect; import android.text.TextUtils; import android.util.ArrayMap; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import com.github.niqdev.mjpeg.OnDrawCompleteListener; import com.github.niqdev.mjpeg.bean.Data; /** * @Author hyj * @Date 2017/10/19 19:16 */ public class MySurfaceView3 extends SurfaceView implements SurfaceHolder.Callback, View.OnTouchListener { private static final int NONE = 0;// 原始 private static final int DRAG = 1;// 拖动 private static final int ZOOM = 2;// 放大 private int mStatus = NONE; private static final float MAX_ZOOM_SCALE = 5f; private static final float MIN_ZOOM_SCALE = 1.0f; private static final float FLOAT_TYPE = 1.0f; private float mCurrentMaxScale = MAX_ZOOM_SCALE; private float mCurrentScale = 1.0f; private Rect mRectSrc = new Rect(); // used for render image. //要绘图的位置 private Rect mRectDes = new Rect(); // used for store size of monitor. 要画图的部分 private int mCenterX, mCenterY; int mSurfaceHeight, mSurfaceWidth, mImageHeight, mImageWidth; private PointF mStartPoint = new PointF(); private float mStartDistance = 0f; private SurfaceHolder mSurHolder = null; private Bitmap mBitmap; /********************画图部分********************/ private Paint shapePaint; private String paintColor = "FA1418";//当前画笔颜色 private int paintWidth = 3;//画笔宽度 private String action = Data.ACTION_DRAW;//画图动作 private String style = Data.STYLE_RECTANGLE;//画图形状 private float startX = 0, startY = 0, endX = 0, endY = 0;//位置比例 private float sx = 0, sy = 0, ex = 0, ey = 0; //计算出来当前屏幕中真实位置 private boolean isDrawShape = false;//当前是否处于画图状态 private ArrayMap<String, Data> amShape; private Data tempShape; private OnDrawCompleteListener<Data> onDrawCompleteListener;//标记绘制完成 /** * 还原所有画图的参数 */ private void restoreDrawParams() { startX = startY = endX = endY = 0; sx = sy = ex = ey = 0; isDrawShape = false; amShape.clear(); } /** * 获得画图状态 * * @return */ public boolean isDrawShape() { return isDrawShape; } /** * 设置画图状态 * * @param drawShape */ public void setDrawShape(boolean drawShape) { isDrawShape = drawShape; } /** * 清空所所有标记、注解 */ public void addMarker(Data dataMarker) { if (null == dataMarker || TextUtils.isEmpty(dataMarker.getAction())) { return; } switch (dataMarker.getAction()) { case Data.ACTION_DRAW: amShape.put(dataMarker.getId(), dataMarker); break; case Data.ACTION_DEL: //TODO 删除指定的图形,预留接口 break; case Data.ACTION_DELALL: restoreDrawParams(); break; } showBitmap(); } /** * 一个图形画完之后的回调事件 * * @param onDrawCompleteListener */ public void setOnDrawCompleteListener(OnDrawCompleteListener onDrawCompleteListener) { this.onDrawCompleteListener = onDrawCompleteListener; } /** * 初始化画图属性 */ private void initDrawShape() { amShape = new ArrayMap<String, Data>(); shapePaint = new Paint(); shapePaint.setAntiAlias(false); shapePaint.setStyle(Paint.Style.STROKE); shapePaint.setStrokeCap(Paint.Cap.ROUND); shapePaint.setStrokeJoin(Paint.Join.ROUND); shapePaint.setColor(Color.parseColor("#" + paintColor)); shapePaint.setStrokeWidth(paintWidth); } /** * 计算点X到图片左上角距离与图片宽度的比值 * * @param bmW 图片宽 * @param pointX 点相对于屏幕左上角的X距离 * @return */ private float pointScreen2ImageX(int bmW, float pointX) { return (pointX / mWidthScale - mRectDes.left + mRectSrc.left) * 1.0f / (bmW); } /** * 计算点Y到图片左上角与图片高度的比值 * * @param bmH 图片高度 * @param pointY 点相对于屏幕左上角的Y距离 * @return */ private float pointScreen2ImageY(int bmH, float pointY) { return (pointY / mHeightScale - mRectDes.top + mRectSrc.top) * 1.0f / (bmH); } /** * 把相对于图片的宽比值转换成相对于屏幕上具体的点 * * @param bmW 图片宽度 * @param scaleX 点的X值相对于图片宽度的比值 * @return */ private float pointImage2ScreenX(int bmW, float scaleX) { return (scaleX * bmW + mRectDes.left - mRectSrc.left) * mWidthScale; } /** * 把相对于图片的高度壁纸转换成相对于屏幕上具体的点 * * @param bmH 图片高度 * @param scaleY 点的Y值相对于图片高度的比值 * @return */ private float pointImage2ScreenY(int bmH, float scaleY) { return (scaleY * bmH + mRectDes.top - mRectSrc.top) * mHeightScale; } /********************画图部分********************/ public MySurfaceView3(Context context, AttributeSet attrs) { super(context, attrs); mSurHolder = getHolder(); mSurHolder.addCallback(this); this.setOnTouchListener(this); } private void init() { mCurrentMaxScale = Math.max(MIN_ZOOM_SCALE, 4 * Math.min(FLOAT_TYPE * mImageHeight / mSurfaceHeight, 1.0f * mImageWidth / mSurfaceWidth)); mCurrentScale = MIN_ZOOM_SCALE; mCenterX = mImageWidth / 2; mCenterY = mImageHeight / 2; initDrawShape(); calcRect(); } private void adjustCenter() { int w = mRectSrc.right - mRectSrc.left; int h = mRectSrc.bottom - mRectSrc.top; if (mCenterX - w / 2 < 0) { mCenterX = w / 2; mRectSrc.left = 0; mRectSrc.right = w; } else if (mCenterX + w / 2 >= mImageWidth) { mCenterX = mImageWidth - w / 2; mRectSrc.right = mImageWidth; mRectSrc.left = mRectSrc.right - w; } else { mRectSrc.left = mCenterX - w / 2; mRectSrc.right = mRectSrc.left + w; } if (mCenterY - h / 2 < 0) { mCenterY = h / 2; mRectSrc.top = 0; mRectSrc.bottom = h; } else if (mCenterY + h / 2 >= mImageHeight) { mCenterY = mImageHeight - h / 2; mRectSrc.bottom = mImageHeight; mRectSrc.top = mRectSrc.bottom - h; } else { mRectSrc.top = mCenterY - h / 2; mRectSrc.bottom = mRectSrc.top + h; } } private float mWidthScale = 1.0f;//当前宽的缩放比例 private float mHeightScale = 1.0f;//当前高的缩放比例 float distanceX; float distancY; private void calcRect() { int w, h; float imageRatio, surfaceRatio; imageRatio = FLOAT_TYPE * mImageWidth / mImageHeight; surfaceRatio = FLOAT_TYPE * mSurfaceWidth / mSurfaceHeight; if (imageRatio < surfaceRatio) { h = mSurfaceHeight; w = (int) (h * imageRatio); } else { w = mSurfaceWidth; h = (int) (w / imageRatio); } if (mCurrentScale > MIN_ZOOM_SCALE) { //如果显示区域超过屏幕宽高,则取屏幕宽高 w = Math.min(mSurfaceWidth, (int) (w * mCurrentScale)); h = Math.min(mSurfaceHeight, (int) (h * mCurrentScale)); } else { mCurrentScale = MIN_ZOOM_SCALE; } String msg = "imageRatio:" + imageRatio + " surfaceRatio:" + surfaceRatio + " mCurrentScale:" + mCurrentScale + " w:" + w + " h:" + h + " mSurfaceWidth:" + mSurfaceWidth + " mSurfaceHeight:" + mSurfaceHeight + " mImageWidth:" + mImageWidth + " mImageHeight:" + mImageHeight; Log.i("TAG radio", msg); mRectDes.left = (mSurfaceWidth - w) / 2; mRectDes.top = (mSurfaceHeight - h) / 2; mRectDes.right = mRectDes.left + w; mRectDes.bottom = mRectDes.top + h; float curImageRatio = FLOAT_TYPE * w / h; int h2, w2; if (curImageRatio > imageRatio) { h2 = (int) (mImageHeight / mCurrentScale); w2 = (int) (h2 * curImageRatio); } else { w2 = (int) (mImageWidth / mCurrentScale); h2 = (int) (w2 / curImageRatio); } mRectSrc.left = mCenterX - w2 / 2; mRectSrc.top = mCenterY - h2 / 2; mRectSrc.right = mRectSrc.left + w2; mRectSrc.bottom = mRectSrc.top + h2; distanceX = (mSurfaceWidth - w) / 2 - (mCenterX - w2 / 2); distancY = (mSurfaceHeight - h) / 2 - (mCenterY - h2 / 2); mWidthScale = w * FLOAT_TYPE / w2;//计算当前宽度缩放比例 mHeightScale = h * FLOAT_TYPE / h2;//计算当前高度缩放比例 } public void setMaxZoom(float value) { mCurrentMaxScale = value; } public void setBitmap(Bitmap b) { if (b == null) { return; } synchronized (MySurfaceView3.class) { mBitmap = b; if (mImageHeight != mBitmap.getHeight() || mImageWidth != mBitmap.getWidth()) { mImageHeight = mBitmap.getHeight(); mImageWidth = mBitmap.getWidth(); init(); } showBitmap(); } } private void showBitmap() { synchronized (MySurfaceView3.class) { Canvas c = getHolder().lockCanvas(); if (c != null && mBitmap != null) { c.drawColor(Color.GRAY); c.drawBitmap(mBitmap, mRectSrc, mRectDes, null); drawShape2Bitmap(c); getHolder().unlockCanvasAndPost(c); } } } private void drawShape2Bitmap(Canvas c) { if (amShape != null && amShape.size() > 0) { for (Data obj : amShape.values()) { shapePaint.setStrokeWidth(obj.getBorderWidth()); shapePaint.setColor(Color.parseColor(obj.getColor2Paint())); switch (obj.getStyle()) { case Data.STYLE_RECTANGLE: sx = pointImage2ScreenX(mImageWidth, obj.getStartPointX()); sy = pointImage2ScreenY(mImageHeight, obj.getStartPointY()); ex = pointImage2ScreenX(mImageWidth, obj.getEndPointX()); ey = pointImage2ScreenY(mImageHeight, obj.getEndPointY()); c.drawRect(sx, sy, ex, ey, shapePaint); break; case Data.STYLE_CIRCLE: //TODO 预留接口画圆 break; } } } //将图片上的点转换为屏幕上的点 if (startX != endX || startY != endY) { sx = pointImage2ScreenX(mImageWidth, startX); sy = pointImage2ScreenY(mImageHeight, startY); ex = pointImage2ScreenX(mImageWidth, endX); ey = pointImage2ScreenY(mImageHeight, endY); c.drawRect(sx, sy, ex, ey, shapePaint); String msg = "mRectSrc:" + mRectSrc.left + "," + mRectSrc.top + "," + mRectSrc.right + "," + mRectSrc.bottom; Log.i("TAG mRectSrc", msg); msg = "mRectDes:" + mRectDes.left + "," + mRectDes.top + "," + mRectDes.right + "," + mRectDes.bottom; Log.i("TAG mRectDes", msg); msg = "pintScale: " + startX + "," + startY + "," + endX + "," + endY; Log.i("TAG pintScale", msg); msg = "point:" + sx + "," + sy + "," + ex + "," + ey; Log.i("TAG point", msg); msg = "bitmap:" + mBitmap.getWidth() + "," + mBitmap.getHeight() + ",放大倍数:" + mCurrentScale + ",mWidthScale:" + mWidthScale + ",mHeightScale:" + mHeightScale; Log.i("TAG bitmap", msg); } } private void dragAction(MotionEvent event) { final int dragScale = 3;//放慢拖动速率 synchronized (MySurfaceView3.class) { PointF currentPoint = new PointF(); currentPoint.set(event.getX(), event.getY()); int offsetX = (int) (currentPoint.x - mStartPoint.x) / dragScale; int offsetY = (int) (currentPoint.y - mStartPoint.y) / dragScale; mStartPoint = currentPoint; mCenterX -= offsetX; mCenterY -= offsetY; adjustCenter(); showBitmap(); } } private void zoomAcition(MotionEvent event) { synchronized (MySurfaceView3.class) { float newDist = spacing(event); float scale = newDist / mStartDistance; mStartDistance = newDist; mCurrentScale *= scale; mCurrentScale = Math.max(FLOAT_TYPE, Math.min(mCurrentScale, mCurrentMaxScale)); calcRect(); adjustCenter(); showBitmap(); } } @Override public boolean onTouch(View v, MotionEvent event) { if (isDrawShape) { if (mRectDes.left > event.getX() || mRectDes.right < event.getX()) { return false; } else if (mRectDes.top > event.getY() || mRectDes.bottom < event.getY()) { return false; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startX = pointScreen2ImageX(mImageWidth, event.getX()); startY = pointScreen2ImageY(mImageHeight, event.getY()); endX = startX; endY = startY; tempShape = new Data(action, style, paintColor, paintWidth); break; case MotionEvent.ACTION_MOVE: endX = pointScreen2ImageX(mImageWidth, event.getX()); endY = pointScreen2ImageY(mImageHeight, event.getY()); break; case MotionEvent.ACTION_UP: endX = pointScreen2ImageX(mImageWidth, event.getX()); endY = pointScreen2ImageY(mImageHeight, event.getY()); tempShape.setStartPoint(startX, startY); tempShape.setEndPoint(endX, endY); if (null != onDrawCompleteListener) { tempShape = onDrawCompleteListener.onDrawCoomplete(tempShape); } amShape.put(tempShape.getId(), tempShape.clone()); break; } showBitmap(); return true; } //缩放部分 switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: mStartPoint.set(event.getX(), event.getY()); mStatus = DRAG; break; case MotionEvent.ACTION_POINTER_DOWN: float distance = spacing(event); if (distance > 10f) { mStatus = ZOOM; mStartDistance = distance; } break; case MotionEvent.ACTION_MOVE: if (mStatus == DRAG) { dragAction(event); } else { if (event.getPointerCount() == 1) return true; zoomAcition(event); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mStatus = NONE; break; } return true; } private float spacing(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return (float) Math.sqrt(x * x + y * y); } @Override public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub } // 初始化 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { synchronized (MySurfaceView3.class) { mRectDes.set(0, 0, width, height); mSurfaceHeight = height; mSurfaceWidth = width; init(); if (mBitmap != null) { showBitmap(); } } } @Override public void surfaceDestroyed(SurfaceHolder holder) { } } ``` XML文件代码 ``` <MySurfaceView3 android:id="@+id/calledMsvZoom" android:layout_width="match_parent" android:layout_height="match_parent" /> ```

怎么在ListView的Item里面去用SurfaceView绘制

package com.example.mysurfaceviewdemo; import java.util.Random; import android.graphics.Bitmap; public class BitmapBubble { private Bitmap mBitmap; private int maxX; private int maxY; private int x; private int y; private boolean isRight = true; private boolean isUp = true; Random random = new Random(); private int speedX = random.nextInt(2)+1; private int speedY = random.nextInt(10)+1; public BitmapBubble(Bitmap mBitmap,int x,int y,int maxX,int maxY){ this.mBitmap = mBitmap; this.x = x; this.y = y; this.maxX = maxX - mBitmap.getWidth(); this.maxY = maxY - mBitmap.getHeight(); } public int getMaxX() { return maxX; } public void setMaxX(int maxX) { this.maxX = maxX; } public int getMaxY() { return maxY; } public void setMaxY(int maxY) { this.maxY = maxY; } public int getX() { x+=speedX; return x; } public int getY() { y-=speedY; return y; } public void setX(int x) { this.x = x; } public void setY(int y) { this.y = y; } public int getSpeedX() { return speedX; } public void setSpeedX(int speedX) { this.speedX = speedX; } public Bitmap getmBitmap() { return mBitmap; } public void setmBitmap(Bitmap mBitmap) { this.mBitmap = mBitmap; } } package com.example.mysurfaceviewdemo; import java.util.ArrayList; import java.util.Random; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuff.Mode; import android.util.AttributeSet; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.RelativeLayout; import android.widget.TextView; public class MySurfaceView extends SurfaceView implements Callback,Runnable{ private SurfaceHolder mSurfaceHolder; private Thread mThread; private Canvas canvas; private int ScreenW, ScreenH; private Random random = new Random(); private ArrayList <BitmapBubble> list = new ArrayList<BitmapBubble>(); int maxY; int maxX; int x ; int y ; private boolean hasBitmapBubble = true; private Bitmap mBitmap; private BitmapBubble mBitmapBubble; private int BitmapIds [] = new int []{R.drawable.water,R.drawable.water2,R.drawable.water3,R.drawable.water4}; public MySurfaceView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initSurfaceView(context); } public MySurfaceView(Context context, AttributeSet attrs) { super(context, attrs); initSurfaceView(context); } public MySurfaceView(Context context) { super(context); initSurfaceView(context); } @Override public void run(){ Canvas canvas = mSurfaceHolder.lockCanvas(); maxX = canvas.getWidth(); maxY = canvas.getHeight(); x = 30; y = maxY-80; mSurfaceHolder.unlockCanvasAndPost(canvas); while(true){ canvas = mSurfaceHolder.lockCanvas(); if(canvas==null){ return; } canvas.drawColor(Color.TRANSPARENT,Mode.CLEAR); for(int j=0; j<list.size();j++){ mBitmapBubble = list.get(j); canvas.drawBitmap(mBitmapBubble.getmBitmap(),mBitmapBubble.getX(), mBitmapBubble.getY(), null); if(mBitmapBubble.getX()>mBitmapBubble.getMaxX()){ list.remove(mBitmapBubble); } if(mBitmapBubble.getY()<0){ list.remove(mBitmapBubble); } } mSurfaceHolder.unlockCanvasAndPost(canvas); try { Thread.sleep(150); } catch (InterruptedException e) { e.printStackTrace(); } } } public void initSurfaceView(Context context){ mSurfaceHolder = this.getHolder(); mSurfaceHolder.addCallback(this); this.setZOrderOnTop(true);//设置画布 背景透明 this.getHolder().setFormat(PixelFormat.TRANSLUCENT); drawBubble(); mThread = new Thread(this); } @Override public void surfaceCreated(SurfaceHolder holder) { mThread.start(); //生产冒泡 new Thread(){ public void run() { while(true){ int position = random.nextInt(4); int resId = BitmapIds[position]; mBitmap = BitmapFactory.decodeResource(getResources(),resId); Bitmap bitmap = Bitmap.createScaledBitmap(mBitmap, 50, 50, false); list.add(new BitmapBubble(bitmap, x, y, maxX, maxY)); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }; }.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { mThread.stop(); } public ArrayList<BitmapBubble> getList() { return list; } public void setList(ArrayList<BitmapBubble> list) { this.list = list; } public void drawBubble(){ mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); Bitmap bitmap = Bitmap.createScaledBitmap(mBitmap, 40, 40, false); list.add(new BitmapBubble(bitmap, x, y, maxX, maxY)); } } package com.example.mysurfaceviewdemo; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; public class MyAdapter extends BaseAdapter{ Context mContext; public MyAdapter(Context mContext){ this.mContext = mContext; } @Override public int getCount() { return 10; } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = LayoutInflater.from(mContext).inflate(R.layout.activity_main, null); final MySurfaceView mySurfaceView = (MySurfaceView)view.findViewById(R.id.mysurfaceview); Button btn = (Button) view.findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mySurfaceView.drawBubble(); } }); return view; } } package com.example.mysurfaceviewdemo; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ListView; public class MainActivity extends Activity { MySurfaceView mySurfaceView; Button btn; ListView listview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout); // setContentView(R.layout.activity_main); // mySurfaceView = (MySurfaceView) findViewById(R.id.mysurfaceview); // btn = (Button) findViewById(R.id.btn); // btn.setOnClickListener(new OnClickListener() { // @Override // public void onClick(View v) { // mySurfaceView.drawBubble(); // } // }); listview = (ListView)findViewById(R.id.listview); listview.setAdapter(new MyAdapter(getApplicationContext())); } } 求大牛教育 ,为什么我在绘制的时候,它的回调不走,但是SurfaceView的宿主是Activity的时候就可以去绘

在SurfaceView extends Surface中定义了class,在里面重载onkeyup,就是执行不了

代码如下: package com.rzy.plane; import java.util.Random; import java.util.Vector; import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.SurfaceHolder.Callback; public class MainActivity extends Activity { MySurfaceView mysurfaceview = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mysurfaceview = new MySurfaceView(this); setContentView(mysurfaceview); } } class MySurfaceView extends SurfaceView implements Callback { private SurfaceHolder sfh; private Paint paint; //定义游戏状态变量 public static final int GAME_MENU = 0; public static final int GAMEING = 1; public static final int GAME_WIN = 2; public static final int GAME_LOST = 3; public static final int GAME_PAUSE = -1; //当前游戏状态(默认初始在游戏菜单界面) public static int gameState = GAME_MENU; public static int screenW; public static int screenH; //声明一个Resources实例便于加载图片 private Resources res = this.getResources(); private Bitmap bmpBackGround;//游戏背景 private Bitmap bmpBoom;//爆炸效果 private Bitmap bmpBoosBoom;//boss爆炸效果 private Bitmap bmpButton;//游戏开始按钮 private Bitmap bmpButtonPress;//游戏开始按钮点击 private Bitmap bmpEnemyduck;//怪物鸭子 private Bitmap bmpEnemyFiy;//怪物苍蝇 private Bitmap bmpEnemyBoss;//怪物boss private Bitmap bmpGameWin;//游戏胜利背景 private Bitmap bmpGameLost;//游戏失败背景 private Bitmap bmpPlayer;//游戏主角飞机 private Bitmap bmpPlayerHp;//游戏主角飞机血量 private Bitmap bmpMenu;//菜单背景 private Bitmap bmpBullet;//子弹 private Bitmap bmpEnmeyBullet;//敌机飞机 private Bitmap bmpBossBullet;//Boss子弹 //声明一个菜单对象 private GameMenu gameMenu; //声明一个滚动游戏背景对象 private GameBg backGround; //声明主角对象 private Player player; String tag = "MySurfaceView"; public MySurfaceView(Context context) { super(context); sfh = this.getHolder(); sfh.addCallback(this); paint = new Paint(); paint.setColor(Color.WHITE); } @Override public void surfaceCreated(SurfaceHolder holder) { screenW = this.getWidth(); screenH = this.getHeight(); initGame(); myDraw(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } public void myDraw() { Canvas canvas = sfh.lockCanvas(); switch (gameState) { case GAME_MENU: gameMenu.draw(canvas, paint); Log.i(tag, "00"); break; case GAMEING: //游戏 背景 backGround.draw(canvas, paint); //主角绘图函数 player.draw(canvas, paint); Log.i(tag, "0"); break; case GAME_WIN: break; case GAME_LOST: break; case GAME_PAUSE: break; } sfh.unlockCanvasAndPost(canvas); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (gameState) { case GAME_MENU: break; case GAMEING: //主角的按键按下事件 player.onKeyDown(keyCode, event); Log.i(tag, "1"); break; case GAME_WIN: break; case GAME_LOST: break; case GAME_PAUSE: break; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { switch (gameState) { case GAME_MENU: break; case GAMEING: //按键抬起事件 player.onKeyUp(keyCode, event); Log.i(tag, "2"); break; case GAME_WIN: break; case GAME_LOST: break; case GAME_PAUSE: break; } return super.onKeyUp(keyCode, event); } @Override public boolean onTouchEvent(MotionEvent event) { // Canvas canvas = sfh.lockCanvas(); switch (gameState) { case GAME_MENU: gameMenu.onTouchEvent(event); Log.i(tag, "1"); myDraw(); break; case GAMEING: break; case GAME_WIN: break; case GAME_LOST: break; case GAME_PAUSE: break; } // sfh.unlockCanvasAndPost(canvas); return true; } private void logic() { switch (gameState) { case GAME_MENU: break; case GAMEING: //背景逻辑 backGround.logic(); //主角逻辑 player.logic(); Log.i(tag, "3"); break; case GAME_WIN: break; case GAME_LOST: break; case GAME_PAUSE: break; } } private void initGame() { if (gameState == GAME_MENU) { bmpBackGround = BitmapFactory.decodeResource(res, R.drawable.background); bmpBoom = BitmapFactory.decodeResource(res, R.drawable.boom); bmpBoosBoom = BitmapFactory.decodeResource(res, R.drawable.boom); bmpButton = BitmapFactory.decodeResource(res, R.drawable.button); bmpButtonPress = BitmapFactory.decodeResource(res, R.drawable.button_press); bmpEnemyduck = BitmapFactory.decodeResource(res, R.drawable.boss_duck); bmpEnemyFiy = BitmapFactory.decodeResource(res, R.drawable.boss_fly); bmpEnemyBoss = BitmapFactory.decodeResource(res, R.drawable.boss_pig); bmpGameWin = BitmapFactory.decodeResource(res, R.drawable.win); bmpGameLost = BitmapFactory.decodeResource(res, R.drawable.lost); bmpPlayer = BitmapFactory.decodeResource(res, R.drawable.zhujue); bmpPlayerHp = BitmapFactory.decodeResource(res, R.drawable.hp); bmpMenu = BitmapFactory.decodeResource(res, R.drawable.menu); bmpBullet = BitmapFactory.decodeResource(res, R.drawable.bullte); bmpEnmeyBullet = BitmapFactory.decodeResource(res, R.drawable.enemy_bullye); bmpBossBullet = BitmapFactory.decodeResource(res, R.drawable.bossbullte); } gameMenu = new GameMenu(bmpMenu, bmpButton, bmpButtonPress); backGround = new GameBg(bmpBackGround); player = new Player(bmpPlayer, bmpPlayerHp); } public class GameMenu { //菜单背景 private Bitmap bmpMenu; //按钮图片资源(按下和未按下图) private Bitmap bmpButton, bmpButtonPress; //按钮坐标 private int btnX, btnY; //按钮标记 private Boolean isPress; //菜单初始化 public GameMenu(Bitmap bmpMenu, Bitmap bmpButton, Bitmap bmpButtonPress) { this.bmpMenu = bmpMenu; this.bmpButton = bmpButton; this.bmpButtonPress = bmpButtonPress; //X居中,Y紧接屏幕底部 btnX = MySurfaceView.screenW / 2 - bmpButton.getWidth() / 2; btnY = MySurfaceView.screenH / 2 - bmpButton.getHeight() / 2; isPress = false; } //菜单绘图函数 public void draw(Canvas canvas, Paint paint) { canvas.drawBitmap(bmpMenu, 0, 0, paint); //绘制未按下按钮图 if(isPress) { canvas.drawBitmap(bmpButtonPress, btnX, btnY, paint); } else { canvas.drawBitmap(bmpButton, btnX, btnY, paint); } } //菜单触屏事件函数,主要用于处理按钮事件 public void onTouchEvent(MotionEvent event) { int pointX = (int) event.getX(); int pointY = (int) event.getY(); if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) { if (pointX > btnX && pointX < btnX + bmpButton.getWidth()) { if (pointY > btnY && pointY < btnY + bmpButton.getHeight()) { isPress = true;Log.i(tag, "TRYE"); } else { isPress = false;Log.i(tag, "FALSE1"); } } else { isPress = false;Log.i(tag, "FALSE2"); } } else if (event.getAction() == MotionEvent.ACTION_UP) { if (pointX > btnX && pointX < btnX + bmpButton.getWidth()) { if (pointY > btnY && pointY < btnY + bmpButton.getHeight()) { isPress = false;Log.i(tag, "FALSE3"); MySurfaceView.gameState = MySurfaceView.GAMEING; } } } } } public class GameBg { //游戏背景的图片资源 //为了循环播放,这里定义两个位图对象 //其资源引用的是同一张图片 private Bitmap bmpBackGround1; private Bitmap bmpBackGround2; //游戏背景坐标 private int bg1x, bg1y, bg2x, bg2y; //背景滚动速度 private int speed = 3; //游戏背景构造函数 public GameBg(Bitmap bmpBackGround) { this.bmpBackGround1 = bmpBackGround; this.bmpBackGround2 = bmpBackGround; //首先让第一张背景底部正好填满整个屏幕 bg1y = -Math.abs(bmpBackGround1.getHeight() - MySurfaceView.screenH); //第二张背景图紧接在第一张背景的上方 //+101的原因:虽然两张背景图无缝隙连接但是因为图片资源头尾 //直接连接不和谐,为了让视觉看不出是两张图连接而修正的位置 bg2y = bg1y - bmpBackGround1.getHeight() + 101; } //游戏背景的绘图函数 public void draw(Canvas canvas, Paint paint) { //绘制两张背景 canvas.drawBitmap(bmpBackGround1, bg1x, bg1y, paint); canvas.drawBitmap(bmpBackGround2, bg2x, bg2y, paint); } //游戏背景的逻辑函数 public void logic() { bg1y += speed; bg2y += speed; //当第一张图片的Y坐标超出屏幕, //立即将其坐标设置到第二张图的上方 if (bg1y > MySurfaceView.screenH) { bg1y = bg2y - bmpBackGround1.getHeight() + 111; } if (bg2y > MySurfaceView.screenH) { bg2y = bg1y - bmpBackGround1.getHeight() + 111; } } } public class Player { //主角血量与血量位图 //默认3血 private int playerHp = 3; private Bitmap bmpPlayerHp; //主角的坐标以及位图 public int x, y; private Bitmap bmpPlayer; //主角移动速度 private int speed = 5; //主角移动白哦是 private boolean isUp, isDown, isLeft, isRight; //主角的构造函数 public Player(Bitmap bmpPlayer, Bitmap bmpPlayerHp) { this.bmpPlayer = bmpPlayer; this.bmpPlayerHp = bmpPlayerHp; x = MySurfaceView.screenW / 2 - bmpPlayer.getWidth() / 2; y = MySurfaceView.screenH - bmpPlayer.getHeight(); } //主角的绘图函数 public void draw(Canvas canvas, Paint paint) { //绘制主角 canvas.drawBitmap(bmpPlayer, x, y, paint); //绘制血量 for (int i = 0; i < playerHp; i++) { canvas.drawBitmap(bmpPlayerHp, i * bmpPlayerHp.getWidth(), MySurfaceView.screenH - bmpPlayerHp.getHeight(), paint); } } //试题按键 public void onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_UP) { isUp = true; } if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { isDown = true; } if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { isLeft = true; } if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { isRight = true; } } //实体按键抬起 public void onKeyUp(int keyCode, KeyEvent event) { Log.i(tag, "player.keyup"); if (keyCode == KeyEvent.KEYCODE_DPAD_UP) { isUp = false; } if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { isDown = false; } if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { isLeft = false; } if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { isRight = false; } } //主角的逻辑 public void logic() { //处理主角移动 if(isLeft) { x -= speed; } if(isRight) { x += speed; } if(isUp) { y -= speed; } if(isDown) { y += speed; } //判断品目X边界 if (x + bmpPlayer.getWidth() >= MySurfaceView.screenW) { x = MySurfaceView.screenW - bmpPlayer.getWidth(); } else if (x <= 0) { x = 0; } //判断品目Y边界 if (y + bmpPlayer.getHeight() >= MySurfaceView.screenH) { y = MySurfaceView.screenH - bmpPlayer.getHeight(); } else if (y <= 0) { y = 0; } } //设置主角血量 public void setPlayerHp(int hp) { this.playerHp = hp; } //获取主角血量 public int getplayerHp() { return playerHp; } } }

surfaceview画滚动的背景图时图片不能完美拼接

![图片说明](https://img-ask.csdn.net/upload/201504/06/1428290687_171361.png) 这是我的代码,要如何改才能去掉中间那根白线,让背景看起来是自然的 public bkground(Bitmap bmpBackGround) { this.bmpBackGround1 = bmpBackGround; this.bmpBackGround2 = bmpBackGround; bg1x = 0; bg2x =800; } //游戏背景的绘图函数 public void draw(Canvas canvas, Paint paint) { //绘制两张背景 canvas.drawBitmap(bmpBackGround1, bg1x, 0, paint); canvas.drawBitmap(bmpBackGround2, bg2x, 0, paint); } //游戏背景的逻辑函数 public void logic() { bg1x -= speed; bg2x -= speed; if (bg1x<-800) { bg1x=bg2x+800; } if (bg2x <-800) { bg2x = bg1x +800; } }

android做的俄罗斯方块,其他界面在手机撒谎能够看都是正常的,就游戏界面不能满屏

package com.comon; //启动游戏 import java.io.InputStream; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; public class StarSurfaceView extends SurfaceView implements Runnable,SurfaceHolder.Callback,View.OnKeyListener { //SurfaceHolder用来完成对绘制的画布进行裁剪,控制其大小 SurfaceHolder sHolder=null; Canvas canvas; Paint paint; showPage tm; contro cm; int face; boolean flag; boolean onlyone=true; boolean next = false; Store a; Store c; int x; int y; int kk; // int action; //创建图片对象 Bitmap store1 = null; Bitmap store2 = null; Bitmap store3 = null; Bitmap store4 = null; Bitmap store5 = null; Bitmap store6 = null; Bitmap store7 = null; Bitmap border1 = null; Bitmap border2 = null; Bitmap record = null; Bitmap num0 = null; Bitmap num1 = null; Bitmap num2 = null; Bitmap num3 = null; Bitmap num4 = null; Bitmap num5 = null; Bitmap num6 = null; Bitmap num7 = null; Bitmap num8 = null; Bitmap num9 = null; Bitmap blg = null; // Bitmap fire = null; Bitmap conti=null; Bitmap goon = null; Bitmap good = null; Bitmap happy = null; Bitmap bbk = null; public StarSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); //实例化sHolder sHolder = this.getHolder(); //addCallback:给SurfaceView添加一个回调函数 sHolder.addCallback(this); this.setFocusable(true); // sHolder = this.getHolder(); // sHolder.addCallback(this); paint=new Paint(); tm = new showPage(); cm = new contro(); a = new Store(); c = new Store(); // action=0; face = 0; x=-2; y=4; kk=0; //获得对象 bbk = this.getBitmapById(R.drawable.bbk); blg = this.getBitmapById(R.drawable.tetris); store1 = this.getBitmapById(R.drawable.block0); store2 = this.getBitmapById(R.drawable.block1); store3 = this.getBitmapById(R.drawable.block2); store4 = this.getBitmapById(R.drawable.block3); store5 = this.getBitmapById(R.drawable.block4); store6 = this.getBitmapById(R.drawable.block5); store7 = this.getBitmapById(R.drawable.block6); border1 = this.getBitmapById(R.drawable.border); border2 = this.getBitmapById(R.drawable.border_sm); num0 = this.getBitmapById(R.drawable.a0); num1 = this.getBitmapById(R.drawable.a1); num2 = this.getBitmapById(R.drawable.a2); num3 = this.getBitmapById(R.drawable.a3); num4 = this.getBitmapById(R.drawable.a4); num5 = this.getBitmapById(R.drawable.a5); num6 = this.getBitmapById(R.drawable.a6); num7 = this.getBitmapById(R.drawable.a7); num8 = this.getBitmapById(R.drawable.a8); num9 = this.getBitmapById(R.drawable.a9); record = this.getBitmapById(R.drawable.record); // fire = this.getBitmapById(R.drawable.fire); conti=this.getBitmapById(R.drawable.conti); goon = this.getBitmapById(R.drawable.goon); good = this.getBitmapById(R.drawable.good); happy = this.getBitmapById(R.drawable.happy); } //从资源中装载图片 public Bitmap getBitmapById(int id) { Bitmap image = null; Context currentCtx = this.getContext();//得到当前设备环境 Resources res = currentCtx.getResources();//得到图片资源 InputStream is = res.openRawResource(id);//打开图片资源 image = BitmapFactory.decodeStream(is);//获取图片资源 return image; } //绘制方法 public void draw() { //// Canvas c = null;//声明画布 // c = sHolder.lockCanvas();//锁定画布 //// Paint p;//声明画笔 // p = new Paint(); // // c.drawBitmap(bbk, 0, 0, p); // c.drawBitmap(border1, 2, 1, p);//绘制游戏主背景 // c.drawBitmap(border2, 240, 20, p);//绘制产生下一个方块的背景 // c.drawBitmap(record, 240, 270, p);//绘制计分榜背景 // showFace(c,p); // showC(c,p); // showT(c,p); // showP(c,p); // sHolder.unlockCanvasAndPost(c);//解锁画布 try { canvas= sHolder.lockCanvas(); if (canvas!= null) { canvas.drawBitmap(bbk,0,0,paint); canvas.drawBitmap(border1, 2,1 ,paint); canvas.drawBitmap(border2,240,20, paint); canvas.drawBitmap(record,240, 270,paint); showFace(canvas,paint); showC(canvas,paint); showT(canvas,paint); showP(canvas,paint); // sHolder.unlockCanvasAndPost(c); } } catch (Exception e) { System.out.println("error"); } finally { if (canvas!= null) sHolder.unlockCanvasAndPost(canvas); } } boolean left = false; boolean right = false; boolean up = false; boolean down = false; // boolean back=false; public void run() { if(onlyone){ // int x = -2; // int y = 4; // boolean next = false; // Store a = new Store(); // Store b = new Store(); c.Sttore(-1);//随机为下一个方块区域生成一个方块 a.Sttore(-1);//随机为游戏区域生成一个方块 tm.putS(c);//在下一个方块区域产生一个方块 onlyone=false; // int kk = 0; //用来控制方块的变形次数,在一行内 } while(flag){ if(next) { tm.delS(c);//删除下一个方块区域的方块 a.Sttore(c.kind);//把存储下一个方块区域的方块的数组传递给游戏区域的方块数组 c.Sttore(-1);//为下一个方块区域随机生成一个方块 x = -2; y = 4; next = false; tm.putS(c); } draw();//绘制方块 //控制方块下降速度 try { Thread.sleep(400 - cm.speed); } catch (InterruptedException e) { e.printStackTrace(); } // if(back){ // Intent intent1 = new Intent(); // intent1.setClass( ActivityGame.acGame, TTetris.class); // ActivityGame.acGame.startActivity(intent1); // ActivityGame.acGame.finish(); // break; // } if(left) { tm.delStore(a, x, y);//删除游戏区域的方块 if(tm.leftM(a, x, y)) { y--; //如果方块可以左移,把方块左移 } tm.putStore(a, x, y);//重新生成左移后的方块 left = false; kk++; if(kk < 3) { continue; } } //方块右移 else if(right) { tm.delStore(a, x, y); if(tm.rightM(a, x, y)) { y++; } tm.putStore(a, x, y); right = false; kk++; if(kk < 3) { continue; } } //方块变形 else if(up) { int tv; if( (a.kind+1)%4 == 0) { //每种方块有1,2,3,4这四种状态,如果处于第4种状态,按上就变回第一种状态 tv = a.kind -3; //否则把没按一次上,1变成2,2变成3,3变成4 } else { tv = a.kind + 1; } Store b = new Store(); b.Sttore(tv); tm.delStore(a, x, y); if(tm.fit(b, x, y)) { //如果方块变形后不会碰壁,则生成一个变形后的方块,否则生成原来的方块 a = b; tm.putStore(a, x, y); up = false; kk++; if(kk < 3) { continue; } } else { tm.putStore(a, x, y); up = false; } } else if(down) { tm.delStore(a, x, y); while(tm.fit(a, x, y)) { x++; } tm.putStore(a, x, y); down = false; } tm.delStore(a, x, y); kk = 0; if(tm.fit(a, x, y)) {//使方块下落 x++; tm.putStore(a, x, y); } else { int t; tm.putStore(a, x, y); if(tm.outM(a, x, y)) {//如果方块触顶了,结束游戏,转换到游戏结束界面 Intent intent = new Intent(); intent.setClass( ActivityGame.acGame, ActGameover.class); ActivityGame.acGame.startActivity(intent); ActivityGame.acGame.finish(); break; } t = tm.flood(a, x, y);//消行,并返回消除的行数,不可以消行返回0; // putface(t); face=t; cm.tscore(t); //计分 cm.passWar(); System.out.println(cm.score); tm.pSco(cm.sco); next = true; } } } public void showFace(Canvas canvas,Paint paint) {//通过face控制人物的表情 if(face == 0) { canvas.drawBitmap(goon, 240,120, paint); } else if(face == 1) { canvas.drawBitmap(conti, 240,120, paint); } else if(face == 2||face==3) { canvas.drawBitmap(good, 240,120, paint); } else if(face==4) { canvas.drawBitmap(happy, 240,120, paint); } } // public void putface(int fa) { //生成face的值 // if(fa == 0) { // face = (int)(Math.random()*2); // } // else { // face = fa+1; // } // } public void showC(Canvas canvas,Paint paint) { //绘制分数的图片 for(int i = 0; i <4; i++) { if(tm.co[i] == 0) { canvas.drawBitmap(num0, i*20+240, 330, paint); } else if(tm.co[i] == 1) { canvas.drawBitmap(num1, i*20+240, 330, paint); } else if(tm.co[i] == 2) { canvas.drawBitmap(num2, i*20+240, 330, paint); } else if(tm.co[i] == 3) { canvas.drawBitmap(num3, i*20+240, 330, paint); } else if(tm.co[i] == 4) { canvas.drawBitmap(num4, i*20+240, 330, paint); } else if(tm.co[i] == 5) { canvas.drawBitmap(num5, i*20+240, 330, paint); } else if(tm.co[i] == 6) { canvas.drawBitmap(num6, i*20+240, 330, paint); } else if(tm.co[i] == 7) { canvas.drawBitmap(num7, i*20+240, 330, paint); } else if(tm.co[i] == 8) { canvas.drawBitmap(num8, i*20+240, 330, paint); } else if(tm.co[i] == 9) { canvas.drawBitmap(num9, i*20+240, 330, paint); } } } public void showT(Canvas canvas,Paint paint) {//下一个方块生成区域的方块绘制不同颜色的方块图片 for(int i = 0 ;i < 4; i++) { for(int j = 0; j < 4; j++) { if(tm.brray[i][j] == 1){ canvas.drawBitmap(store1, j*tm.w+240, i*tm.w+20, paint); } else if(tm.brray[i][j] == 2){ canvas.drawBitmap(store2, j*tm.w+240, i*tm.w+20, paint); } else if(tm.brray[i][j] == 3){ canvas.drawBitmap(store3, j*tm.w+240, i*tm.w+20, paint); } else if(tm.brray[i][j] == 4){ canvas.drawBitmap(store4, j*tm.w+240, i*tm.w+20, paint); } else if(tm.brray[i][j] == 5){ canvas.drawBitmap(store5, j*tm.w+240, i*tm.w+20, paint); } else if(tm.brray[i][j] == 6){ canvas.drawBitmap(store6, j*tm.w+240, i*tm.w+20, paint); } else if(tm.brray[i][j] == 7){ canvas.drawBitmap(store7, j*tm.w+240, i*tm.w+20, paint); } } } } public void showP(Canvas canvas,Paint paint) { //为游戏区域的方块绘制不同颜色的图片 for(int i = 0 ;i < tm.array.length; i++){ for(int j = 0; j < tm.array[0].length; j++){ if(tm.array[i][j] == 1){ canvas.drawBitmap(store1, j*tm.w-1, i*tm.w-2, paint); } else if(tm.array[i][j] == 2){ canvas.drawBitmap(store2, j*tm.w-1, i*tm.w-2, paint); } else if(tm.array[i][j] == 3){ canvas.drawBitmap(store3, j*tm.w-1, i*tm.w-2, paint); } else if(tm.array[i][j] == 4){ canvas.drawBitmap(store4, j*tm.w-1, i*tm.w-2, paint); } else if(tm.array[i][j] == 5){ canvas.drawBitmap(store5, j*tm.w-1, i*tm.w-2, paint); } else if(tm.array[i][j] == 6){ canvas.drawBitmap(store6, j*tm.w-1, i*tm.w-2, paint); } else if(tm.array[i][j] == 7){ canvas.drawBitmap(store7, j*tm.w-1, i*tm.w-2, paint); } } } } public boolean onKeyDown(int k, KeyEvent event) { return false; } public boolean onKeyUp(int k,KeyEvent event){ switch (k) { case KeyEvent.KEYCODE_DPAD_UP: up=true; break; case KeyEvent.KEYCODE_DPAD_DOWN: down=true; break; case KeyEvent.KEYCODE_DPAD_LEFT: left=true; break; case KeyEvent.KEYCODE_DPAD_RIGHT: right=true; break; } return false; } public boolean onKey(View v, int k, KeyEvent e) { return false; } public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) { } public void surfaceCreated(SurfaceHolder holder) { flag=true; Thread th = new Thread(this); th.start(); } public void surfaceDestroyed(SurfaceHolder holder) { flag=false; } } main()的代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation = "vertical" > <com.comon.StarSurfaceView android:layout_width="fill_parent" android:layout_height="fill_parent" ></com.comon.StarSurfaceView> </LinearLayout>

android开发报错log信息如下,小弟新手,求问是什么错误,错在哪,如何解决

02-21 20:41:34.969: W/dalvikvm(20654): threadid=11: thread exiting with uncaught exception (group=0x40abf228) 02-21 20:41:34.969: E/AndroidRuntime(20654): FATAL EXCEPTION: Thread-6366 02-21 20:41:34.969: E/AndroidRuntime(20654): java.lang.IllegalArgumentException 02-21 20:41:34.969: E/AndroidRuntime(20654): at android.view.Surface.unlockCanvasAndPost(Native Method) 02-21 20:41:34.969: E/AndroidRuntime(20654): at android.view.SurfaceView$4.unlockCanvasAndPost(SurfaceView.java:819) 02-21 20:41:34.969: E/AndroidRuntime(20654): at com.himi.MySurfaceView.draw(MySurfaceView.java:66) 02-21 20:41:34.969: E/AndroidRuntime(20654): at com.himi.MySurfaceView.run(MySurfaceView.java:85) 02-21 20:41:34.969: E/AndroidRuntime(20654): at java.lang.Thread.run(Thread.java:864) 02-21 20:41:35.089: D/memalloc(20654): /dev/pmem: Mapped buffer base:0x54554000 size:28688384 offset:26599424 fd:77 02-21 20:41:35.409: D/memalloc(20654): /dev/pmem: Unmapping buffer base:0x52a1a000 size:26599424 offset:24510464 02-21 20:41:35.409: D/memalloc(20654): /dev/pmem: Unmapping buffer base:0x54554000 size:28688384 offset:26599424 02-21 20:41:38.222: D/Process(20654): killProcess, pid=20654 02-21 20:41:38.222: D/Process(20654): dalvik.system.VMStack.getThreadStackTrace(Native Method) 02-21 20:41:38.252: D/Process(20654): java.lang.Thread.getStackTrace(Thread.java:599) 02-21 20:41:38.252: D/Process(20654): android.os.Process.killProcess(Process.java:790) 02-21 20:41:38.252: D/Process(20654): com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:104) enter code here package com.himi; import java.util.Vector; //Download by http://www.codefans.net import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.SurfaceHolder.Callback; public class MySurfaceView extends SurfaceView implements Callback, Runnable { private Thread th; private SurfaceHolder sfh; private Canvas canvas; private Paint p; public static Vector<Bitmap> vec_bmp; public static Vector<String> vec_string; private int col; public MySurfaceView(Context context, AttributeSet attrs) { super(context, attrs); p = new Paint(); p.setAntiAlias(true); sfh = this.getHolder(); sfh.addCallback(this); th = new Thread(this); this.setKeepScreenOn(true); setFocusable(true); vec_string = new Vector<String>(); vec_bmp = new Vector<Bitmap>(); } public void surfaceCreated(SurfaceHolder holder) { col = this.getWidth() / 100; th.start(); } public void draw() { try { canvas = sfh.lockCanvas(); if (canvas != null) { canvas.drawColor(Color.BLACK); if (vec_bmp != null && vec_bmp.size() != 0) { for (int i = 0; i < vec_bmp.size(); i++) { Bitmap bitmap = vec_bmp.elementAt(i); p.setStyle(Style.STROKE); canvas.drawRect((i % col) * 104 + 1, (i / col) * 100 + 1, (i % col) * 104 + 104 - 2, (i / col) * 100 + 100 - 2, p); canvas.drawBitmap(bitmap, (i % col) * 100, (i / col) * 100, p); p.setColor(Color.YELLOW); canvas.drawText(vec_string.elementAt(i), (i % col) * 104 + 10, (i / col) * 100 + 97, p); p.setColor(Color.WHITE); } } } } catch (Exception e) { // TODO: handle exception } finally { sfh.unlockCanvasAndPost(canvas); } } @Override public boolean onKeyDown(int key, KeyEvent event) { return super.onKeyDown(key, event); } @Override public boolean onTouchEvent(MotionEvent event) { return true; } public void run() { // TODO Auto-generated method stub while (true) { draw(); try { Thread.sleep(100); } catch (Exception ex) { } } } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub } }

jbox2d游戏引擎问题,求高手解答!

我用jbox2d写了一个例子为什么跑不起来啊,我用的是jbox2d的最新版本,求高手赐教,谢谢!请看代码。 package com.example.androidxuexi; import org.jbox2d.collision.shapes.CircleShape; import org.jbox2d.common.Vec2; import org.jbox2d.dynamics.Body; import org.jbox2d.dynamics.BodyDef; import org.jbox2d.dynamics.FixtureDef; import org.jbox2d.dynamics.World; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; import com.example.android.R; public class MyView_11 extends SurfaceView implements Callback, Runnable { private SurfaceHolder sur; private Canvas canvas; private Paint paint; private Thread t; private boolean threadFlag; private Bitmap ball; private float ball_x, ball_y; private float screen_width, screen_height; private float ground_x, ground_y; private Bitmap ground; private World world; private Vec2 gravity; private final float RATE = 30; private float timeStep = 1 / 60; private int velocityIterations = 10; private int positionIterations = 8; public MyView_11(Context context) { super(context); sur = this.getHolder(); sur.addCallback(this); paint = new Paint(); paint.setAntiAlias(true); gravity = new Vec2(0, 10); world = new World(gravity, true); } public Body createCircle(float x, float y, float r) { CircleShape circle = new CircleShape(); circle.m_radius = r / RATE; FixtureDef fDef = new FixtureDef(); fDef.density = 2.1f; fDef.friction = 0.5f; fDef.restitution = 0.3f; fDef.shape = circle; BodyDef bodyDef = new BodyDef(); bodyDef.position.set(x / RATE, y / RATE); Body body = world.createBody(bodyDef); body.m_userData = ball; body.createFixture(fDef); return body; } public void logic() { world.step(timeStep, velocityIterations, positionIterations); Body body = world.getBodyList(); Vec2 position = body.getPosition(); ball_x = position.x * RATE; ball_y = position.y * RATE; } public void initBitmap() { ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball); ground = BitmapFactory .decodeResource(getResources(), R.drawable.ground); ground_x = 0; ground_y = screen_height - ground.getHeight(); ball_x = screen_width / 2 - ball.getWidth() / 2; ball_y = 50 + screen_height / 20; } public void myDraw() { try { canvas = sur.lockCanvas(); if (canvas != null) { canvas.drawColor(Color.BLACK); canvas.drawBitmap(ball, ball_x, ball_y, paint); canvas.drawBitmap(ground, ground_x, ground_y, paint); } } catch (Exception e) { } finally { if (canvas != null) { sur.unlockCanvasAndPost(canvas); } } } @Override public void run() { if (threadFlag) { long startTime = System.currentTimeMillis(); logic(); myDraw(); long endTime = System.currentTimeMillis(); if ((endTime - startTime) < 50) { try { Thread.sleep(50 - (endTime - startTime)); } catch (InterruptedException e) { e.printStackTrace(); } } } } @Override public void surfaceCreated(SurfaceHolder holder) { screen_width = this.getWidth(); screen_height = this.getHeight(); initBitmap(); createCircle(ball_x, ball_y, ball.getHeight() / 2); threadFlag = true; t = new Thread(this); t.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { release(); threadFlag = false; } private void release() { if (!ball.isRecycled()) { ball.recycle(); } } }

重力感应控制画布小球问题

import android.app.Activity; import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.Window; import android.view.WindowManager; import android.view.SurfaceHolder.Callback; public class SurfaceViewAcitvity extends Activity { MyView mAnimView = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 全屏显示窗口 requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //强制横屏 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // 显示自定义的游戏View mAnimView = new MyView(this); setContentView(mAnimView); } public class MyView extends SurfaceView implements Callback,Runnable ,SensorEventListener{ /**每50帧刷新一次屏幕**/ public static final int TIME_IN_FRAME = 50; /** 游戏画笔 **/ Paint mPaint = null; Paint mTextPaint = null; SurfaceHolder mSurfaceHolder = null; /** 控制游戏更新循环 **/ boolean mRunning = false; /** 游戏画布 **/ Canvas mCanvas = null; /**控制游戏循环**/ boolean mIsRunning = false; /**SensorManager管理器**/ private SensorManager mSensorMgr = null; Sensor mSensor = null; /**手机屏幕宽高**/ int mScreenWidth = 0; int mScreenHeight = 0; /**小球资源文件越界区域**/ private int mScreenBallWidth = 0; private int mScreenBallHeight = 0; /**游戏背景文件**/ private Bitmap mbitmapBg; /**小球资源文件**/ private Bitmap mbitmapBall; /**小球的坐标位置**/ private float mPosX = 200; private float mPosY = 0; /**重力感应X轴 Y轴 Z轴的重力值**/ private float mGX = 0; private float mGY = 0; private float mGZ = 0; public MyView(Context context) { super(context); /** 设置当前View拥有控制焦点 **/ this.setFocusable(true); /** 设置当前View拥有触摸事件 **/ this.setFocusableInTouchMode(true); /** 拿到SurfaceHolder对象 **/ mSurfaceHolder = this.getHolder(); /** 将mSurfaceHolder添加到Callback回调函数中 **/ mSurfaceHolder.addCallback(this); /** 创建画布 **/ mCanvas = new Canvas(); /** 创建曲线画笔 **/ mPaint = new Paint(); mPaint.setColor(Color.WHITE); /**加载小球资源**/ mbitmapBall = BitmapFactory.decodeResource(this.getResources(), R.drawable.ball); /**加载游戏背景**/ mbitmapBg = BitmapFactory.decodeResource(this.getResources(), R.drawable.bg); /**得到SensorManager对象**/ mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); mSensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // 注册listener,第三个参数是检测的精确度 //SENSOR_DELAY_FASTEST 最灵敏 因为太快了没必要使用 //SENSOR_DELAY_GAME 游戏开发中使用 //SENSOR_DELAY_NORMAL 正常速度 //SENSOR_DELAY_UI 最慢的速度 mSensorMgr.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME); } private void Draw() { /**绘制游戏背景**/ mCanvas.drawBitmap(mbitmapBg,0,0, mPaint); /**绘制小球**/ mCanvas.drawBitmap(mbitmapBall, mPosX,mPosY, mPaint); /**X轴 Y轴 Z轴的重力值**/ mCanvas.drawText("X轴重力值 :" + mGX, 0, 20, mPaint); mCanvas.drawText("Y轴重力值 :" + mGY, 0, 40, mPaint); mCanvas.drawText("Z轴重力值 :" + mGZ, 0, 60, mPaint); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { /**开始游戏主循环线程**/ mIsRunning = true; new Thread(this).start(); /**得到当前屏幕宽高**/ mScreenWidth = this.getWidth(); mScreenHeight = this.getHeight(); /**得到小球越界区域**/ mScreenBallWidth = mScreenWidth - mbitmapBall.getWidth(); mScreenBallHeight = mScreenHeight - mbitmapBall.getHeight(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { mIsRunning = false; } @Override public void run() { while (mIsRunning) { /** 取得更新游戏之前的时间 **/ long startTime = System.currentTimeMillis(); /** 在这里加上线程安全锁 **/ synchronized (mSurfaceHolder) { /** 拿到当前画布 然后锁定 **/ mCanvas = mSurfaceHolder.lockCanvas(); Draw(); /** 绘制结束后解锁显示在屏幕上 **/ mSurfaceHolder.unlockCanvasAndPost(mCanvas); } /** 取得更新游戏结束的时间 **/ long endTime = System.currentTimeMillis(); /** 计算出游戏一次更新的毫秒数 **/ int diffTime = (int) (endTime - startTime); /** 确保每次更新时间为50帧 **/ while (diffTime <= TIME_IN_FRAME) { diffTime = (int) (System.currentTimeMillis() - startTime); /** 线程等待 **/ Thread.yield(); } } } @Override public void onAccuracyChanged(Sensor arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onSensorChanged(SensorEvent event) { mGX = event.values[SensorManager.DATA_X]; mGY= event.values[SensorManager.DATA_Y]; mGZ = event.values[SensorManager.DATA_Z]; //这里乘以2是为了让小球移动的更快 mPosX -= mGX * 2; mPosY += mGY * 2; //检测小球是否超出边界 if (mPosX < 0) { mPosX = 0; } else if (mPosX > mScreenBallWidth) { mPosX = mScreenBallWidth; } if (mPosY < 0) { mPosY = 0; } else if (mPosY > mScreenBallHeight) { mPosY = mScreenBallHeight; } } } } 这时用重力感应器控制小球移动的一个demo,但是现在我想自己画一个圆充当小球,而不是用图片替代,我该怎么改这段代码?求指教!

“Unfortunately, app name has stopped.”android设备或者是模拟器

我在根据一些教程来创建app,当我想要运行app的时候,没有显示错误,但是在emulator显示"Unfortunately, Viewfinder blabla has stopped." 代码: AndroidManifest.xml file <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.viewfinderee368" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ViewfinderEE368" android:label="@string/app_name" android:screenOrientation="landscape"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="6"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-feature android:name="android.hardware.camera"/> <uses-feature android:name="android.hardware.camera.autofocus"/> </manifest> src/.java file package com.example.viewfinderee368; import java.io.IOException; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.hardware.Camera; import android.hardware.Camera.PreviewCallback; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.view.ViewGroup.LayoutParams; // ---------------------------------------------------------------------- public class ViewfinderEE368 extends Activity { private Preview mPreview; private DrawOnTop mDrawOnTop; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 隐藏窗口标题H getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); requestWindowFeature(Window.FEATURE_NO_TITLE); //创建预览视图然后将它设置为activity的目录 //创建DrawOnTop视图. mDrawOnTop = new DrawOnTop(this); mPreview = new Preview(this, mDrawOnTop); setContentView(mPreview); addContentView(mDrawOnTop, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); } } //---------------------------------------------------------------------- class DrawOnTop extends View { Bitmap mBitmap; Paint mPaintBlack; Paint mPaintYellow; Paint mPaintRed; Paint mPaintGreen; Paint mPaintBlue; byte[] mYUVData; int[] mRGBData; int mImageWidth, mImageHeight; int[] mRedHistogram; int[] mGreenHistogram; int[] mBlueHistogram; double[] mBinSquared; public DrawOnTop(Context context) { super(context); mPaintBlack = new Paint(); mPaintBlack.setStyle(Paint.Style.FILL); mPaintBlack.setColor(Color.BLACK); mPaintBlack.setTextSize(25); mPaintYellow = new Paint(); mPaintYellow.setStyle(Paint.Style.FILL); mPaintYellow.setColor(Color.YELLOW); mPaintYellow.setTextSize(25); mPaintRed = new Paint(); mPaintRed.setStyle(Paint.Style.FILL); mPaintRed.setColor(Color.RED); mPaintRed.setTextSize(25); mPaintGreen = new Paint(); mPaintGreen.setStyle(Paint.Style.FILL); mPaintGreen.setColor(Color.GREEN); mPaintGreen.setTextSize(25); mPaintBlue = new Paint(); mPaintBlue.setStyle(Paint.Style.FILL); mPaintBlue.setColor(Color.BLUE); mPaintBlue.setTextSize(25); mBitmap = null; mYUVData = null; mRGBData = null; mRedHistogram = new int[256]; mGreenHistogram = new int[256]; mBlueHistogram = new int[256]; mBinSquared = new double[256]; for (int bin = 0; bin < 256; bin++) { mBinSquared[bin] = ((double)bin) * bin; } // bin } @Override protected void onDraw(Canvas canvas) { if (mBitmap != null) { int canvasWidth = canvas.getWidth(); int canvasHeight = canvas.getHeight(); int newImageWidth = canvasWidth; int newImageHeight = canvasHeight; int marginWidth = (canvasWidth - newImageWidth)/2; // 从YUV转换成RGB decodeYUV420SP(mRGBData, mYUVData, mImageWidth, mImageHeight); // 画位图 // mBitmap.setPixels(mRGBData, 0, mImageWidth, 0, 0, // mImageWidth, mImageHeight); // Rect src = new Rect(0, 0, mImageWidth, mImageHeight); // Rect dst = new Rect(marginWidth, 0, // canvasWidth-marginWidth, canvasHeight); // canvas.drawBitmap(mBitmap, src, dst, mPaintBlack); // 画黑色边缘 // canvas.drawRect(0, 0, marginWidth, canvasHeight, mPaintBlack); // canvas.drawRect(canvasWidth - marginWidth, 0, // canvasWidth, canvasHeight, mPaintBlack); // 计算直方图 calculateIntensityHistogram(mRGBData, mRedHistogram, mImageWidth, mImageHeight, 0); calculateIntensityHistogram(mRGBData, mGreenHistogram, mImageWidth, mImageHeight, 1); calculateIntensityHistogram(mRGBData, mBlueHistogram, mImageWidth, mImageHeight, 2); // 计算平均值 double imageRedMean = 0, imageGreenMean = 0, imageBlueMean = 0; double redHistogramSum = 0, greenHistogramSum = 0, blueHistogramSum = 0; for (int bin = 0; bin < 256; bin++) { imageRedMean += mRedHistogram[bin] * bin; redHistogramSum += mRedHistogram[bin]; imageGreenMean += mGreenHistogram[bin] * bin; greenHistogramSum += mGreenHistogram[bin]; imageBlueMean += mBlueHistogram[bin] * bin; blueHistogramSum += mBlueHistogram[bin]; } // bin imageRedMean /= redHistogramSum; imageGreenMean /= greenHistogramSum; imageBlueMean /= blueHistogramSum; double imageRed2ndMoment = 0, imageGreen2ndMoment = 0, imageBlue2ndMoment = 0; for (int bin = 0; bin < 256; bin++) { imageRed2ndMoment += mRedHistogram[bin] * mBinSquared[bin]; imageGreen2ndMoment += mGreenHistogram[bin] * mBinSquared[bin]; imageBlue2ndMoment += mBlueHistogram[bin] * mBinSquared[bin]; } // bin imageRed2ndMoment /= redHistogramSum; imageGreen2ndMoment /= greenHistogramSum; imageBlue2ndMoment /= blueHistogramSum; double imageRedStdDev = Math.sqrt( imageRed2ndMoment - imageRedMean*imageRedMean ); double imageGreenStdDev = Math.sqrt( imageGreen2ndMoment - imageGreenMean*imageGreenMean ); double imageBlueStdDev = Math.sqrt( imageBlue2ndMoment - imageBlueMean*imageBlueMean ); // 画平均值 String imageMeanStr = "Mean (R,G,B): " + String.format("%.4g", imageRedMean) + ", " + String.format("%.4g", imageGreenMean) + ", " + String.format("%.4g", imageBlueMean); canvas.drawText(imageMeanStr, marginWidth+10-1, 30-1, mPaintBlack); canvas.drawText(imageMeanStr, marginWidth+10+1, 30-1, mPaintBlack); canvas.drawText(imageMeanStr, marginWidth+10+1, 30+1, mPaintBlack); canvas.drawText(imageMeanStr, marginWidth+10-1, 30+1, mPaintBlack); canvas.drawText(imageMeanStr, marginWidth+10, 30, mPaintYellow); // 画标准差 String imageStdDevStr = "Std Dev (R,G,B): " + String.format("%.4g", imageRedStdDev) + ", " + String.format("%.4g", imageGreenStdDev) + ", " + String.format("%.4g", imageBlueStdDev); canvas.drawText(imageStdDevStr, marginWidth+10-1, 60-1, mPaintBlack); canvas.drawText(imageStdDevStr, marginWidth+10+1, 60-1, mPaintBlack); canvas.drawText(imageStdDevStr, marginWidth+10+1, 60+1, mPaintBlack); canvas.drawText(imageStdDevStr, marginWidth+10-1, 60+1, mPaintBlack); canvas.drawText(imageStdDevStr, marginWidth+10, 60, mPaintYellow); // 画红色直方图 float barMaxHeight = 3000; float barWidth = ((float)newImageWidth) / 256; float barMarginHeight = 2; RectF barRect = new RectF(); barRect.bottom = canvasHeight - 200; barRect.left = marginWidth; barRect.right = barRect.left + barWidth; for (int bin = 0; bin < 256; bin++) { float prob = (float)mRedHistogram[bin] / (float)redHistogramSum; barRect.top = barRect.bottom - Math.min(80,prob*barMaxHeight) - barMarginHeight; canvas.drawRect(barRect, mPaintBlack); barRect.top += barMarginHeight; canvas.drawRect(barRect, mPaintRed); barRect.left += barWidth; barRect.right += barWidth; } // bin // 画绿色直方图 barRect.bottom = canvasHeight - 100; barRect.left = marginWidth; barRect.right = barRect.left + barWidth; for (int bin = 0; bin < 256; bin++) { barRect.top = barRect.bottom - Math.min(80, ((float)mGreenHistogram[bin])/((float)greenHistogramSum) * barMaxHeight) - barMarginHeight; canvas.drawRect(barRect, mPaintBlack); barRect.top += barMarginHeight; canvas.drawRect(barRect, mPaintGreen); barRect.left += barWidth; barRect.right += barWidth; } // bin // 画蓝色直方图 barRect.bottom = canvasHeight; barRect.left = marginWidth; barRect.right = barRect.left + barWidth; for (int bin = 0; bin < 256; bin++) { barRect.top = barRect.bottom - Math.min(80, ((float)mBlueHistogram[bin])/((float)blueHistogramSum) * barMaxHeight) - barMarginHeight; canvas.drawRect(barRect, mPaintBlack); barRect.top += barMarginHeight; canvas.drawRect(barRect, mPaintBlue); barRect.left += barWidth; barRect.right += barWidth; } // bin } //结束条件语句 super.onDraw(canvas); } // 结束onDraw方法 static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) { final int frameSize = width * height; for (int j = 0, yp = 0; j < height; j++) { int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; for (int i = 0; i < width; i++, yp++) { int y = (0xff & ((int) yuv420sp[yp])) - 16; if (y < 0) y = 0; if ((i & 1) == 0) { v = (0xff & yuv420sp[uvp++]) - 128; u = (0xff & yuv420sp[uvp++]) - 128; } int y1192 = 1192 * y; int r = (y1192 + 1634 * v); int g = (y1192 - 833 * v - 400 * u); int b = (y1192 + 2066 * u); if (r < 0) r = 0; else if (r > 262143) r = 262143; if (g < 0) g = 0; else if (g > 262143) g = 262143; if (b < 0) b = 0; else if (b > 262143) b = 262143; rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); } } } static public void decodeYUV420SPGrayscale(int[] rgb, byte[] yuv420sp, int width, int height) { final int frameSize = width * height; for (int pix = 0; pix < frameSize; pix++) { int pixVal = (0xff & ((int) yuv420sp[pix])) - 16; if (pixVal < 0) pixVal = 0; if (pixVal > 255) pixVal = 255; rgb[pix] = 0xff000000 | (pixVal << 16) | (pixVal << 8) | pixVal; } } static public void calculateIntensityHistogram(int[] rgb, int[] histogram, int width, int height, int component) { for (int bin = 0; bin < 256; bin++) { histogram[bin] = 0; } // bin if (component == 0) // red { for (int pix = 0; pix < width*height; pix += 3) { int pixVal = (rgb[pix] >> 16) & 0xff; histogram[ pixVal ]++; } // pix } else if (component == 1) // green { for (int pix = 0; pix < width*height; pix += 3) { int pixVal = (rgb[pix] >> 8) & 0xff; histogram[ pixVal ]++; } // pix } else // blue { for (int pix = 0; pix < width*height; pix += 3) { int pixVal = rgb[pix] & 0xff; histogram[ pixVal ]++; } // pix } } } // ---------------------------------------------------------------------- class Preview extends SurfaceView implements SurfaceHolder.Callback { SurfaceHolder mHolder; Camera mCamera; DrawOnTop mDrawOnTop; boolean mFinished; Preview(Context context, DrawOnTop drawOnTop) { super(context); mDrawOnTop = drawOnTop; mFinished = false; // 安装SurfaceHolder.Callback以便当下垫面被创建和销毁的时候我们能够获得通知 mHolder = getHolder(); mHolder.addCallback(this); mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public void surfaceCreated(SurfaceHolder holder) { mCamera = Camera.open(); try { mCamera.setPreviewDisplay(holder); mCamera.setPreviewCallback(new PreviewCallback() { public void onPreviewFrame(byte[] data, Camera camera) { if ( (mDrawOnTop == null) || mFinished ) return; if (mDrawOnTop.mBitmap == null) { // 初始化draw-on-top companion Camera.Parameters params = camera.getParameters(); mDrawOnTop.mImageWidth = params.getPreviewSize().width; mDrawOnTop.mImageHeight = params.getPreviewSize().height; mDrawOnTop.mBitmap = Bitmap.createBitmap(mDrawOnTop.mImageWidth, mDrawOnTop.mImageHeight, Bitmap.Config.RGB_565); mDrawOnTop.mRGBData = new int[mDrawOnTop.mImageWidth * mDrawOnTop.mImageHeight]; mDrawOnTop.mYUVData = new byte[data.length]; } System.arraycopy(data, 0, mDrawOnTop.mYUVData, 0, data.length); mDrawOnTop.invalidate(); } }); } catch (IOException exception) { mCamera.release(); mCamera = null; } } public void surfaceDestroyed(SurfaceHolder holder) { // 但给我们返回的时候,Surface将被摧毁,所以停止预览 // 因为CameraDevice object不是共享的对象,所以当activity停止的时候要释放它。这个很重要。 mFinished = true; mCamera.setPreviewCallback(null); mCamera.stopPreview(); mCamera.release(); mCamera = null; } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // 现在这个大小是知道的,设置相机参数然后开始预览 Camera.Parameters parameters = mCamera.getParameters(); parameters.setPreviewSize(320, 240); parameters.setPreviewFrameRate(15); parameters.setSceneMode(Camera.Parameters.SCENE_MODE_NIGHT); parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); mCamera.setParameters(parameters); mCamera.startPreview(); } } 我尝试在真机下和模拟器下运行,但是错误都一样 LogCat 11-20 02:50:38.943: E/AndroidRuntime(614): FATAL EXCEPTION: main 11-20 02:50:38.943: E/AndroidRuntime(614): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.viewfinderee368/com.example.viewfinderee368.ViewfinderEE368}: android.util.AndroidRuntimeException: requestFeature() must be called before adding content 11-20 02:50:38.943: E/AndroidRuntime(614): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059) 11-20 02:50:38.943: E/AndroidRuntime(614): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 11-20 02:50:38.943: E/AndroidRuntime(614): at android.app.ActivityThread.access$600(ActivityThread.java:130) 11-20 02:50:38.943: E/AndroidRuntime(614): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 11-20 02:50:38.943: E/AndroidRuntime(614): at android.os.Handler.dispatchMessage(Handler.java:99) 11-20 02:50:38.943: E/AndroidRuntime(614): at android.os.Looper.loop(Looper.java:137) 11-20 02:50:38.943: E/AndroidRuntime(614): at android.app.ActivityThread.main(ActivityThread.java:4745) 11-20 02:50:38.943: E/AndroidRuntime(614): at java.lang.reflect.Method.invokeNative(Native Method) 11-20 02:50:38.943: E/AndroidRuntime(614): at java.lang.reflect.Method.invoke(Method.java:511) 11-20 02:50:38.943: E/AndroidRuntime(614): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 11-20 02:50:38.943: E/AndroidRuntime(614): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 11-20 02:50:38.943: E/AndroidRuntime(614): at dalvik.system.NativeStart.main(Native Method) 11-20 02:50:38.943: E/AndroidRuntime(614): Caused by: android.util.AndroidRuntimeException: requestFeature() must be called before adding content 11-20 02:50:38.943: E/AndroidRuntime(614): at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:215) 11-20 02:50:38.943: E/AndroidRuntime(614): at android.app.Activity.requestWindowFeature(Activity.java:3225) 11-20 02:50:38.943: E/AndroidRuntime(614): at com.example.viewfinderee368.ViewfinderEE368.onCreate(ViewfinderEE368.java:52) 11-20 02:50:38.943: E/AndroidRuntime(614): at android.app.Activity.performCreate(Activity.java:5008) 11-20 02:50:38.943: E/AndroidRuntime(614): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079) 11-20 02:50:38.943: E/AndroidRuntime(614): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023) 11-20 02:50:38.943: E/AndroidRuntime(614): ... 11 more

在中国程序员是青春饭吗?

今年,我也32了 ,为了不给大家误导,咨询了猎头、圈内好友,以及年过35岁的几位老程序员……舍了老脸去揭人家伤疤……希望能给大家以帮助,记得帮我点赞哦。 目录: 你以为的人生 一次又一次的伤害 猎头界的真相 如何应对互联网行业的「中年危机」 一、你以为的人生 刚入行时,拿着傲人的工资,想着好好干,以为我们的人生是这样的: 等真到了那一天,你会发现,你的人生很可能是这样的: ...

程序员请照顾好自己,周末病魔差点一套带走我。

程序员在一个周末的时间,得了重病,差点当场去世,还好及时挽救回来了。

技术大佬:我去,你写的 switch 语句也太老土了吧

昨天早上通过远程的方式 review 了两名新来同事的代码,大部分代码都写得很漂亮,严谨的同时注释也很到位,这令我非常满意。但当我看到他们当中有一个人写的 switch 语句时,还是忍不住破口大骂:“我擦,小王,你丫写的 switch 语句也太老土了吧!” 来看看小王写的代码吧,看完不要骂我装逼啊。 private static String createPlayer(PlayerTypes p...

和黑客斗争的 6 天!

互联网公司工作,很难避免不和黑客们打交道,我呆过的两家互联网公司,几乎每月每天每分钟都有黑客在公司网站上扫描。有的是寻找 Sql 注入的缺口,有的是寻找线上服务器可能存在的漏洞,大部分都...

上班一个月,后悔当初着急入职的选择了

最近有个老铁,告诉我说,上班一个月,后悔当初着急入职现在公司了。他之前在美图做手机研发,今年美图那边今年也有一波组织优化调整,他是其中一个,在协商离职后,当时捉急找工作上班,因为有房贷供着,不能没有收入来源。所以匆忙选了一家公司,实际上是一个大型外包公司,主要派遣给其他手机厂商做外包项目。**当时承诺待遇还不错,所以就立马入职去上班了。但是后面入职后,发现薪酬待遇这块并不是HR所说那样,那个HR自...

女程序员,为什么比男程序员少???

昨天看到一档综艺节目,讨论了两个话题:(1)中国学生的数学成绩,平均下来看,会比国外好?为什么?(2)男生的数学成绩,平均下来看,会比女生好?为什么?同时,我又联想到了一个技术圈经常讨...

总结了 150 余个神奇网站,你不来瞅瞅吗?

原博客再更新,可能就没了,之后将持续更新本篇博客。

副业收入是我做程序媛的3倍,工作外的B面人生是怎样的?

提到“程序员”,多数人脑海里首先想到的大约是:为人木讷、薪水超高、工作枯燥…… 然而,当离开工作岗位,撕去层层标签,脱下“程序员”这身外套,有的人生动又有趣,马上展现出了完全不同的A/B面人生! 不论是简单的爱好,还是正经的副业,他们都干得同样出色。偶尔,还能和程序员的特质结合,产生奇妙的“化学反应”。 @Charlotte:平日素颜示人,周末美妆博主 大家都以为程序媛也个个不修边幅,但我们也许...

如果你是老板,你会不会踢了这样的员工?

有个好朋友ZS,是技术总监,昨天问我:“有一个老下属,跟了我很多年,做事勤勤恳恳,主动性也很好。但随着公司的发展,他的进步速度,跟不上团队的步伐了,有点...

我入职阿里后,才知道原来简历这么写

私下里,有不少读者问我:“二哥,如何才能写出一份专业的技术简历呢?我总感觉自己写的简历太烂了,所以投了无数份,都石沉大海了。”说实话,我自己好多年没有写过简历了,但我认识的一个同行,他在阿里,给我说了一些他当年写简历的方法论,我感觉太牛逼了,实在是忍不住,就分享了出来,希望能够帮助到你。 01、简历的本质 作为简历的撰写者,你必须要搞清楚一点,简历的本质是什么,它就是为了来销售你的价值主张的。往深...

外包程序员的幸福生活

今天给你们讲述一个外包程序员的幸福生活。男主是Z哥,不是在外包公司上班的那种,是一名自由职业者,接外包项目自己干。接下来讲的都是真人真事。 先给大家介绍一下男主,Z哥,老程序员,是我十多年前的老同事,技术大牛,当过CTO,也创过业。因为我俩都爱好喝酒、踢球,再加上住的距离不算远,所以一直也断断续续的联系着,我对Z哥的状况也有大概了解。 Z哥几年前创业失败,后来他开始干起了外包,利用自己的技术能...

优雅的替换if-else语句

场景 日常开发,if-else语句写的不少吧??当逻辑分支非常多的时候,if-else套了一层又一层,虽然业务功能倒是实现了,但是看起来是真的很不优雅,尤其是对于我这种有强迫症的程序"猿",看到这么多if-else,脑袋瓜子就嗡嗡的,总想着解锁新姿势:干掉过多的if-else!!!本文将介绍三板斧手段: 优先判断条件,条件不满足的,逻辑及时中断返回; 采用策略模式+工厂模式; 结合注解,锦...

深入剖析Springboot启动原理的底层源码,再也不怕面试官问了!

大家现在应该都对Springboot很熟悉,但是你对他的启动原理了解吗?

离职半年了,老东家又发 offer,回不回?

有小伙伴问松哥这个问题,他在上海某公司,在离职了几个月后,前公司的领导联系到他,希望他能够返聘回去,他很纠结要不要回去? 俗话说好马不吃回头草,但是这个小伙伴既然感到纠结了,我觉得至少说明了两个问题:1.曾经的公司还不错;2.现在的日子也不是很如意。否则应该就不会纠结了。 老实说,松哥之前也有过类似的经历,今天就来和小伙伴们聊聊回头草到底吃不吃。 首先一个基本观点,就是离职了也没必要和老东家弄的苦...

2020阿里全球数学大赛:3万名高手、4道题、2天2夜未交卷

阿里巴巴全球数学竞赛( Alibaba Global Mathematics Competition)由马云发起,由中国科学技术协会、阿里巴巴基金会、阿里巴巴达摩院共同举办。大赛不设报名门槛,全世界爱好数学的人都可参与,不论是否出身数学专业、是否投身数学研究。 2020年阿里巴巴达摩院邀请北京大学、剑桥大学、浙江大学等高校的顶尖数学教师组建了出题组。中科院院士、美国艺术与科学院院士、北京国际数学...

男生更看重女生的身材脸蛋,还是思想?

往往,我们看不进去大段大段的逻辑。深刻的哲理,往往短而精悍,一阵见血。问:产品经理挺漂亮的,有点心动,但不知道合不合得来。男生更看重女生的身材脸蛋,还是...

为什么程序员做外包会被瞧不起?

二哥,有个事想询问下您的意见,您觉得应届生值得去外包吗?公司虽然挺大的,中xx,但待遇感觉挺低,马上要报到,挺纠结的。

当HR压你价,说你只值7K,你该怎么回答?

当HR压你价,说你只值7K时,你可以流畅地回答,记住,是流畅,不能犹豫。 礼貌地说:“7K是吗?了解了。嗯~其实我对贵司的面试官印象很好。只不过,现在我的手头上已经有一份11K的offer。来面试,主要也是自己对贵司挺有兴趣的,所以过来看看……”(未完) 这段话主要是陪HR互诈的同时,从公司兴趣,公司职员印象上,都给予对方正面的肯定,既能提升HR的好感度,又能让谈判气氛融洽,为后面的发挥留足空间。...

面试:第十六章:Java中级开发(16k)

HashMap底层实现原理,红黑树,B+树,B树的结构原理 Spring的AOP和IOC是什么?它们常见的使用场景有哪些?Spring事务,事务的属性,传播行为,数据库隔离级别 Spring和SpringMVC,MyBatis以及SpringBoot的注解分别有哪些?SpringMVC的工作原理,SpringBoot框架的优点,MyBatis框架的优点 SpringCould组件有哪些,他们...

面试阿里p7,被按在地上摩擦,鬼知道我经历了什么?

面试阿里p7被问到的问题(当时我只知道第一个):@Conditional是做什么的?@Conditional多个条件是什么逻辑关系?条件判断在什么时候执...

你期望月薪4万,出门右拐,不送,这几个点,你也就是个初级的水平

先来看几个问题通过注解的方式注入依赖对象,介绍一下你知道的几种方式@Autowired和@Resource有何区别说一下@Autowired查找候选者的...

面试了一个 31 岁程序员,让我有所触动,30岁以上的程序员该何去何从?

最近面试了一个31岁8年经验的程序猿,让我有点感慨,大龄程序猿该何去何从。

大三实习生,字节跳动面经分享,已拿Offer

说实话,自己的算法,我一个不会,太难了吧

程序员垃圾简历长什么样?

已经连续五年参加大厂校招、社招的技术面试工作,简历看的不下于万份 这篇文章会用实例告诉你,什么是差的程序员简历! 疫情快要结束了,各个公司也都开始春招了,作为即将红遍大江南北的新晋UP主,那当然要为小伙伴们做点事(手动狗头)。 就在公众号里公开征简历,义务帮大家看,并一一点评。《启舰:春招在即,义务帮大家看看简历吧》 一石激起千层浪,三天收到两百多封简历。 花光了两个星期的所有空闲时...

《Oracle Java SE编程自学与面试指南》最佳学习路线图2020年最新版(进大厂必备)

正确选择比瞎努力更重要!

《Oracle Java SE编程自学与面试指南》最佳学习路线图(2020最新版)

正确选择比瞎努力更重要!

字节跳动面试官竟然问了我JDBC?

轻松等回家通知

面试官:你连SSO都不懂,就别来面试了

大厂竟然要考我SSO,卧槽。

终于,月薪过5万了!

来看几个问题想不想月薪超过5万?想不想进入公司架构组?想不想成为项目组的负责人?想不想成为spring的高手,超越99%的对手?那么本文内容是你必须要掌握的。本文主要详解bean的生命...

自从喜欢上了B站这12个UP主,我越来越觉得自己是个废柴了!

不怕告诉你,我自从喜欢上了这12个UP主,哔哩哔哩成为了我手机上最耗电的软件,几乎每天都会看,可是吧,看的越多,我就越觉得自己是个废柴,唉,老天不公啊,不信你看看…… 间接性踌躇满志,持续性混吃等死,都是因为你们……但是,自己的学习力在慢慢变强,这是不容忽视的,推荐给你们! 都说B站是个宝,可是有人不会挖啊,没事,今天咱挖好的送你一箩筐,首先啊,我在B站上最喜欢看这个家伙的视频了,为啥 ,咱撇...

代码注释如此沙雕,会玩还是你们程序员!

某站后端代码被“开源”,同时刷遍全网的,还有代码里的那些神注释。 我们这才知道,原来程序员个个都是段子手;这么多年来,我们也走过了他们的无数套路… 首先,产品经理,是永远永远吐槽不完的!网友的评论也非常扎心,说看这些代码就像在阅读程序员的日记,每一页都写满了对产品经理的恨。 然后,也要发出直击灵魂的质问:你是尊贵的付费大会员吗? 这不禁让人想起之前某音乐app的穷逼Vip,果然,穷逼在哪里都是...

2020春招面试了10多家大厂,我把问烂了的数据库事务知识点总结了一下

2020年截止目前,我面试了阿里巴巴、腾讯、美团、拼多多、京东、快手等互联网大厂。我发现数据库事务在面试中出现的次数非常多。

立即提问
相关内容推荐