编辑:我看了看LogCat,它说它无法给com.example.playground充气.然后我意识到它需要我com.game.myapp.Playground.我改变它后它起作用了.
我最近问为什么引力不能在我的Android应用程序(link)中工作,我仍然遇到麻烦.我将视图更改为“Playground”类,但现在它只是强制关闭.我究竟做错了什么?
package com.game.myapp;
import android.app.Activity;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
public class InGame extends Activity{
Playground v;
private int radius;
private int xPosition;
private int yPosition;
private Paint paint;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Rewrite this, it sucks. Seriously.
super.onCreate(savedInstanceState);
v = new Playground(this);
setContentView(v);
}
public InGame(int x, int y, int radius, int color)
{
this.xPosition = x; this.yPosition = y; this.radius = radius;
paint = new Paint(color);
}
void moveBall(int x, int y){
xPosition = x; yPosition =y;
}
void onDraw(Canvas canvas){
canvas.drawCircle(xPosition, yPosition, radius, paint);
}
}
游乐场类:
package com.game.myapp;
import android.content.Context;
import android.graphics.Canvas;
import android.view.View;
public class Playground extends View{
public static InGame ball;
public Playground(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
if (ball != null ){
ball.onDraw(canvas);
}
}
}
继承LogCat:
11-04 16:36:33.945: D/dalvikvm(13177): newInstance failed: no <init>()
11-04 16:36:33.949: D/AndroidRuntime(13177): Shutting down VM
11-04 16:36:33.949: W/dalvikvm(13177): threadid=1: thread exiting with uncaught exception (group=0x4001e578)
11-04 16:36:33.953: E/AndroidRuntime(13177): FATAL EXCEPTION: main
11-04 16:36:33.953: E/AndroidRuntime(13177): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.game.myapp/com.game.myapp.InGame}: java.lang.InstantiationException: com.game.myapp.InGame
11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1573)
11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
11-04 16:36:33.953: E/AndroidRuntime(13177): at android.os.Handler.dispatchMessage(Handler.java:99)
11-04 16:36:33.953: E/AndroidRuntime(13177): at android.os.Looper.loop(Looper.java:130)
11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.ActivityThread.main(ActivityThread.java:3687)
11-04 16:36:33.953: E/AndroidRuntime(13177): at java.lang.reflect.Method.invokeNative(Native Method)
11-04 16:36:33.953: E/AndroidRuntime(13177): at java.lang.reflect.Method.invoke(Method.java:507)
11-04 16:36:33.953: E/AndroidRuntime(13177): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
11-04 16:36:33.953: E/AndroidRuntime(13177): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
11-04 16:36:33.953: E/AndroidRuntime(13177): at dalvik.system.NativeStart.main(Native Method)
11-04 16:36:33.953: E/AndroidRuntime(13177): Caused by: java.lang.InstantiationException: com.game.myapp.InGame
11-04 16:36:33.953: E/AndroidRuntime(13177): at java.lang.Class.newInstanceImpl(Native Method)
11-04 16:36:33.953: E/AndroidRuntime(13177): at java.lang.Class.newInstance(Class.java:1409)
11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
11-04 16:36:33.953: E/AndroidRuntime(13177): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1565)
11-04 16:36:33.953: E/AndroidRuntime(13177): ... 11 more
解决方法:
这是完整的代码.我刚刚写了这个并测试了它.有用.我为活动添加了一个计时器,每秒向右和向下移动球10个像素.请研究它,从中学习并根据您的需要进行调整.
球类.
package com.example;
import android.graphics.Canvas;
import android.graphics.Paint;
public class Ball{
private int radius;
private int xPosition;
private int yPosition;
private int color;
private Paint paint;
public Ball(int x, int y, int radius, int color)
{
this.xPosition = x; this.yPosition = y; this.radius = radius;
paint = new Paint();
paint.setColor(color);
}
int getX(){return this.xPosition;}
int getY(){return this.yPosition;}
void moveBall(int x, int y){
xPosition = x; yPosition =y;
}
void onDraw(Canvas canvas){
canvas.drawCircle(xPosition, yPosition, radius, paint);
}
}
游乐场课
package com.example;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.ImageView;
public class Playground extends ImageView {
private Ball ball;
public Playground(Context context) {
this(context,null);
}
public Playground(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public Playground(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setBall(Ball ball){
this.ball = ball;
}
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
if (ball != null ){
ball.onDraw(canvas);
}
}
}
活动类
package com.example;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import java.util.Timer;
import java.util.TimerTask;
public class MyActivity extends Activity {
/**
* Called when the activity is first created.
*/
Playground playground;
Ball ball;
Timer myTimer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
playground = (Playground) findViewById(R.id.playground);
ball = new Ball(100, 100, 20, Color.RED);
playground.setBall(ball);
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
@Override
public void run() {
Update();
}
}, 0, 1000);
}
private void Update() {
this.runOnUiThread(moveBall);
}
private Runnable moveBall = new Runnable() {
public void run() {
ball.moveBall(ball.getX() + 10, ball.getY() + 10);
playground.invalidate();
}
};
}
[编辑] XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.example.Playground
android:id="@+id/playground"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
OOP的关键点.
Ball不了解游乐场或活动.它有一个方法,可能会被要求它在画布上绘制的东西调用但是它知道它可能是一个不可见的画布,或按钮的画布,或位图的画布 – 它不知道或需要知道.这是所谓的方法担心的任务.
游乐场不了解活动或球.它知道它可能有一个Ball类的实例,如果它有,它应该调用它的onDraw方法,但它不知道球是什么或它绘制什么. Ball担心这一点.
活动不知道Ball或Playground,除了它有一个,并调用Ball移动方法然后告诉Playground重绘自己.
关键是,您可以更改绘制方法,移动方法和其他所有内容而无需重新编码(一般情况下都可以).例如,您可以更改Ball类中的onDraw以绘制矩形.当然,班级的名字现在是一个糟糕的选择,但你明白了……