当我运行PaintView.java
时,我在logcat中收到以下错误,即无法实例化类com.example.connectthedots.PaintView
;没有空的构造函数。
07-22 18:47:43.453: D/dalvikvm(19728): newInstance failed: no <init>()
07-22 18:47:43.453: D/AndroidRuntime(19728): Shutting down VM
07-22 18:47:43.453: W/dalvikvm(19728): threadid=1: thread exiting with uncaught exception (group=0x41bf6da0)
07-22 18:47:43.453: E/AndroidRuntime(19728): FATAL EXCEPTION: main
07-22 18:47:43.453: E/AndroidRuntime(19728): Process: com.example.connectthedots, PID: 19728
07-22 18:47:43.453: E/AndroidRuntime(19728): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.connectthedots/com.example.connectthedots.PaintView}: java.lang.InstantiationException: can't instantiate class com.example.connectthedots.PaintView; no empty constructor
07-22 18:47:43.453: E/AndroidRuntime(19728): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2231)
07-22 18:47:43.453: E/AndroidRuntime(19728): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2363)
07-22 18:47:43.453: E/AndroidRuntime(19728): at android.app.ActivityThread.access$900(ActivityThread.java:161)
07-22 18:47:43.453: E/AndroidRuntime(19728): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
07-22 18:47:43.453: E/AndroidRuntime(19728): at android.os.Handler.dispatchMessage(Handler.java:102)
07-22 18:47:43.453: E/AndroidRuntime(19728): at android.os.Looper.loop(Looper.java:157)
07-22 18:47:43.453: E/AndroidRuntime(19728): at android.app.ActivityThread.main(ActivityThread.java:5356)
07-22 18:47:43.453: E/AndroidRuntime(19728): at java.lang.reflect.Method.invokeNative(Native Method)
07-22 18:47:43.453: E/AndroidRuntime(19728): at java.lang.reflect.Method.invoke(Method.java:515)
07-22 18:47:43.453: E/AndroidRuntime(19728): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
07-22 18:47:43.453: E/AndroidRuntime(19728): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
07-22 18:47:43.453: E/AndroidRuntime(19728): at dalvik.system.NativeStart.main(Native Method)
07-22 18:47:43.453: E/AndroidRuntime(19728): Caused by: java.lang.InstantiationException: can't instantiate class com.example.connectthedots.PaintView; no empty constructor
07-22 18:47:43.453: E/AndroidRuntime(19728): at java.lang.Class.newInstanceImpl(Native Method)
07-22 18:47:43.453: E/AndroidRuntime(19728): at java.lang.Class.newInstance(Class.java:1208)
07-22 18:47:43.453: E/AndroidRuntime(19728): at android.app.Instrumentation.newActivity(Instrumentation.java:1079)
07-22 18:47:43.453: E/AndroidRuntime(19728): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2222)
07-22 18:47:43.453: E/AndroidRuntime(19728): ... 11 more
我的PaintView.java看起来像这样:
package com.example.connectthedots;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
public class PaintView extends View {
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mPaint;
private static final int TOUCH_TOLERANCE_DP = 24;
private static final int BACKGROUND = 0xFFDDDDDD;
private List<Point> mPoints = new ArrayList<Point>();
private int mLastPointIndex = 0;
private int mTouchTolerance;
private boolean isPathStarted = false;
public PaintView(Context context) {
super(context);
mCanvas = new Canvas();
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP);
// TODO just test points
Point p1 = new Point(20, 20);
Point p2 = new Point(100, 100);
Point p3 = new Point(200, 250);
Point p4 = new Point(280, 400);
Point p5 = new Point(350, 600);
Point p6 = new Point(400, 500);
mPoints.add(p1);
mPoints.add(p2);
mPoints.add(p3);
mPoints.add(p4);
mPoints.add(p5);
mPoints.add(p6);
}
public PaintView(Context context, AttributeSet attrs) {
super(context, attrs);
mCanvas = new Canvas();
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP);
// TODO just test points
Point p1 = new Point(20, 20);
Point p2 = new Point(100, 100);
Point p3 = new Point(200, 250);
Point p4 = new Point(280, 400);
Point p5 = new Point(350, 600);
Point p6 = new Point(400, 500);
mPoints.add(p1);
mPoints.add(p2);
mPoints.add(p3);
mPoints.add(p4);
mPoints.add(p5);
mPoints.add(p6);
}
public PaintView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mCanvas = new Canvas();
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP);
}
@Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
super.onSizeChanged(width, height, oldWidth, oldHeight);
clear();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(BACKGROUND);
canvas.drawBitmap(mBitmap, 0, 0, null);
canvas.drawPath(mPath, mPaint);
// TODO remove if you dont want points to be drawn
for (Point point : mPoints) {
canvas.drawPoint(point.x, point.y, mPaint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up(x, y);
invalidate();
break;
}
return true;
}
private void touch_start(float x, float y) {
if (checkPoint(x, y, mLastPointIndex)) {
mPath.reset();
// user starts from given point so path can beis started
isPathStarted = true;
} else {
// user starts move from point which doen's belongs to mPinst list
isPathStarted = false;
}
}
//ADDED WITH LAST EDIT
private void touch_move(float x, float y) {
// draw line with finger move
if (isPathStarted) {
mPath.reset();
Point p = mPoints.get(mLastPointIndex);
mPath.moveTo(p.x, p.y);
mPath.lineTo(x, y);
}
}
/**
* Draws line.
*/
private void touch_up(float x, float y) {
mPath.reset();
if (checkPoint(x, y, mLastPointIndex + 1) && isPathStarted) {
// move finished at valid point so draw whole line
// start point
Point p = mPoints.get(mLastPointIndex);
mPath.moveTo(p.x, p.y);
// end point
p = mPoints.get(mLastPointIndex + 1);
mPath.lineTo(p.x, p.y);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
// increment point index
++mLastPointIndex;
isPathStarted = false;
}
}
/**
* Sets paint
*
* @param paint
*/
public void setPaint(Paint paint) {
this.mPaint = paint;
}
/**
* Returns image as bitmap
*
* @return
*/
public Bitmap getBitmap() {
return mBitmap;
}
/**
* Clears canvas
*/
public void clear() {
mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
mBitmap.eraseColor(BACKGROUND);
mCanvas.setBitmap(mBitmap);
invalidate();
}
/**
* Checks if user touch point with some tolerance
*/
private boolean checkPoint(float x, float y, int pointIndex) {
if (pointIndex == mPoints.size()) {
// out of bounds
return false;
}
Point point = mPoints.get(pointIndex);
//EDIT changed point.y to poin.x in the first if statement
if (x > (point.x - mTouchTolerance) && x < (point.x + mTouchTolerance)) {
if (y > (point.y - mTouchTolerance) && y < (point.y + mTouchTolerance)) {
return true;
}
}
return false;
}
public List<Point> getPoints() {
return mPoints;
}
public void setPoints(List<Point> points) {
this.mPoints = points;
}
private int dp2px(int dp) {
Resources r = getContext().getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());
return (int) px;
}
}
仅供参考:activity_paint_view.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PaintView" >
<com.example.connectthedots.PaintView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
这里的错误是什么?
答案 0 :(得分:3)
引起:java.lang.InstantiationException:无法实例化类com.example.connectthedots.PaintView;没有空构造函数
如异常所示,PaintView
需要一个没有任何参数的构造函数:
public PaintView() {
...
}
答案 1 :(得分:0)
添加一个空的构造函数:
public PaintView() {
}
答案 2 :(得分:0)
我认为简单地添加一个空构造函数是最好的解决方案。如果要实例化并使用PaintView
对象,则应使用已定义的构造函数之一。如果你看一下Android View Documentation,就没有空的构造函数。由于你有一个View
的子类,实现一个空的构造函数并没有用。
相反,我建议您查看用于创建PaintView
对象的代码。现在,你可能有一些东西:
PaintView mPaintView = new PaintView();
相反,您应该使用已经实现的构造函数之一:
PaintView mPaintView = new PaintView(mContext);
此实例中mContext
是有效的Context
对象。如果您在Activity
中执行此操作,则可以将该Activity
的当前实例传递给构造函数。