我在Google Play上发布了一个应用程序,并且我一直在为7英寸及以上的设备获取崩溃报告。我的游戏使用设备的加速度计,因此我将代码用于检查加速度计,并且仅在找到一个加速度计时继续游戏。事情是崩溃的设备有加速度计。我已经彻底分析了我的代码,我不明白为什么游戏不能在平板电脑上运行所以我认为我会得到其他人的观点。崩溃总是在onCreate中的nullPointerException我的mainActivity但错误报告没有指定在哪里。
这是我的MainActivity代码:
public class MainActivity extends ActionBarActivity {
private MediaPlayer mediaPlayer;
android.graphics.PointF mBallPos, mBallSpd;
int mScrWidth, mScrHeight;
Handler RedrawHandler = new Handler(); //so redraw occurs in main thread
Timer mTmr = null;
TimerTask mTsk = null;
BallView mBallView = null;
int n = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button playGameButton = (Button) findViewById(R.id.playGameButton);
final Button turnOffAdsButton = (Button) findViewById(R.id.turnOffAdsButton);
final Button shareButton = (Button) findViewById(R.id.shareButton);
final Button rateButton = (Button) findViewById(R.id.rateButton);
final TextView musicTextView = (TextView) findViewById(R.id.musicTextView);
final TextView instructionsTextView = (TextView) findViewById(R.id.instructionsTextView);
final TextView titleTextView = (TextView) findViewById(R.id.titleTextView);
Intent intent = getIntent();
n = intent.getIntExtra("adsNumber", 0);
final RelativeLayout mainView = (RelativeLayout) findViewById(R.id.game_title);
//get screen dimensions
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
mScrWidth = metrics.widthPixels;
mScrHeight = metrics.heightPixels;
mBallPos = new PointF();
mBallSpd = new PointF();
//create variables for ball position and speed
mBallPos.x = mScrWidth / 2;
mBallPos.y = mScrHeight / 2;
mBallSpd.x = 0;
mBallSpd.y = 0;
//create initial ball
mBallView = new BallView(this, mBallPos.x, mBallPos.y, mScrWidth/30);
mBallView.setColor(0xFFFFFFFF);
mainView.addView(mBallView); //add ball to main screen
mBallView.invalidate(); //call onDraw in BallView
//listener for accelerometer, use anonymous class for simplicity
((SensorManager) getSystemService(Context.SENSOR_SERVICE)).registerListener(
new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
//set ball speed based on phone tilt (ignore Z axis)
mBallSpd.x = -event.values[0] * 6;
mBallSpd.y = event.values[1] * 6;
//timer event will redraw ball
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
} //ignore
},
((SensorManager) getSystemService(Context.SENSOR_SERVICE))
.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0),
SensorManager.SENSOR_DELAY_NORMAL);
//Check if device has an accelerometer
SensorManager sensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (accelerometerSensor != null)
{
runCircle(); //Begins sampling
}
else {
showAccelerometerFragment();
}
mediaPlayer = MediaPlayer.create(this, R.raw.chopin);
mediaPlayer.setLooping(true);
mediaPlayer.start();
runOnUiThread(new Runnable() {
@Override
public void run() {
YoYo.with(Techniques.Wobble)
.duration(3000)
.playOn(titleTextView);
}
});
runOnUiThread(new Runnable() {
@Override
public void run() {
YoYo.with(Techniques.BounceIn)
.duration(2000)
.playOn(playGameButton);
}
});
runOnUiThread(new Runnable() {
@Override
public void run() {
YoYo.with(Techniques.BounceIn)
.duration(2000)
.playOn(shareButton);
}
});
runOnUiThread(new Runnable() {
@Override
public void run() {
YoYo.with(Techniques.BounceIn)
.duration(2000)
.playOn(turnOffAdsButton);
}
});
runOnUiThread(new Runnable() {
@Override
public void run() {
YoYo.with(Techniques.BounceIn)
.duration(2000)
.playOn(rateButton);
}
});
runOnUiThread(new Runnable() {
@Override
public void run() {
YoYo.with(Techniques.RotateInUpLeft)
.duration(1000)
.playOn(musicTextView);
}
});
runOnUiThread(new Runnable() {
@Override
public void run() {
YoYo.with(Techniques.RotateInDownRight)
.duration(1000)
.playOn(instructionsTextView);
}
});
playGameButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
goToGameScreen();
}
});
musicTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mediaPlayer.isPlaying())
{
//stop or pause your media player mediaPlayer.stop(); or mediaPlayer.pause();
mediaPlayer.pause();
musicTextView.setText("Turn Music On");
} else
{
mediaPlayer.start();
musicTextView.setText("Turn Music Off");
}
}
});
shareButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, getResources().getString(R.string.sharing_string) + "\n\n https://play.google.com/store/apps/details?id=benyamephrem.tilt&hl=en");
sendIntent.setType("text/plain");
startActivity(sendIntent);
}
});
instructionsTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showInstructionFragment();
}
});
rateButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
rateGameRedirect();
}
});
turnOffAdsButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
turnOffAdsRedirect();
}
});
}
@Override
public void onPause() //app moved to background, stop background threads
{ super.onPause();
mediaPlayer.release();
}
private void turnOffAdsRedirect() {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=benyamephrem.tilt&hl=en")));
} catch (ActivityNotFoundException anfe){
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=benyamephrem.tilt&hl=en")));
}
}
private void rateGameRedirect() {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=benyamephrem.tilt&hl=en")));
} catch (ActivityNotFoundException anfe){
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=benyamephrem.tilt&hl=en")));
}
}
public void goToGameScreen(){
Intent intent = new Intent(this, GameScreen.class);
intent.putExtra("adsNumber", n);
startActivity(intent);
}
private void showInstructionFragment() {
InstructionsFragment dialog = new InstructionsFragment();
dialog.show(getFragmentManager(), "instruction_dialog");
}
private void showAccelerometerFragment() {
AccelerometerFragment dialog = new AccelerometerFragment();
dialog.show(getFragmentManager(), "instruction_dialog");
}
private void runCircle() {
//create timer to move ball to new position
mTmr = new Timer();
mTsk = new TimerTask() {
public void run() {
//move ball based on current speed
mBallPos.x += mBallSpd.y;
mBallPos.y += -mBallSpd.x;
//if ball goes off screen, reposition to opposite side of screen
if (mBallPos.x > mScrWidth) mBallPos.x = 0;
if (mBallPos.y > mScrHeight) mBallPos.y = 0;
if (mBallPos.x < 0) mBallPos.x = mScrWidth;
if (mBallPos.y < 0) mBallPos.y = mScrHeight;
//update ball class instance
mBallView.x = mBallPos.x;
mBallView.y = mBallPos.y;
//redraw ball. Must run in background thread to prevent thread lock.
RedrawHandler.post(new Runnable() {
public void run() {
mBallView.invalidate();
}
});
} //run
}; // TimerTask
mTmr.schedule(mTsk, 0, 10); //start timer (Timer)
}
}
这是我的清单:
<?xml version="1.0" encoding="utf-8"?>
<supports-screens android:smallScreens="false"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity
android:name=".UI.MainActivity"
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>
<activity
android:name=".UI.GameScreen"
android:label="@string/title_activity_game_screen"
android:screenOrientation="landscape"
android:parentActivityName=".UI.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="benyamephrem.tilt.UI.MainActivity" />
</activity>
<activity
android:name=".UI.Redirect"
android:label="@string/title_activity_redirect"
android:screenOrientation="landscape"
android:parentActivityName=".UI.GameScreen" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="benyamephrem.tilt.UI.GameScreen" />
</activity>
</application>
这是我在开发者控制台中遇到的错误:
java.lang.RuntimeException: Unable to start activity : java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1973)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1999)
at android.app.ActivityThread.access$600(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1159)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4513)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:974)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:741)
at dalvik.system.NativeStart.main(Native Method)
Caused by: jav
a.lang.NullPointerException
at benyamephrem.tilt.UI.MainActivity.onCreate(Unknown Source)
at android.app.Activity.performCreate(Activity.java:4465)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1932)
... 11 more