Android Studio错误:FATAL EXCEPTION:main(java.lang.IllegalStateException:无法执行android的方法:onClick)

时间:2016-07-02 13:51:19

标签: java android

我正在编写一个跟踪跑步距离的跑步/健身应用程序。它在Android Studio中看起来很好,但在运行应用程序时会出现一些错误。这是代码:

     public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, LocationListener {

private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
public static final String TAG = "FitnessApp";
private LocationRequest mLocationRequest;
public LatLng latLng, latLngStart;
public Pair pair;
Handler Handler = new Handler();
private long startTime, elapsedTime;
private final int REFRESH_RATE = 100;
private String hours, minutes, seconds;
private long secs, mins, hrs;
private boolean stopped = false;
public int dist;
public int Speed;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    mLocationRequest = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(10 * 1000)        // 10 seconds, in milliseconds
            .setFastestInterval(1 * 1000); // 1 second, in milliseconds
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    latLng = new LatLng (1.3263, 103.8026);
    mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    Log.i(TAG, "Location services connected.");
    Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    if (location == null) {
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    } else {
        handleNewLocation(location);
    }
}

@Override
public void onConnectionSuspended(int i) {
    Log.i(TAG, "Location services suspended. Please reconnect.");
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    if (connectionResult.hasResolution()) {
        try {
            // Start an Activity that tries to resolve the error
            connectionResult.startResolutionForResult(this, CAUSE_SERVICE_DISCONNECTED);
        } catch (IntentSender.SendIntentException e) {
            e.printStackTrace();
        }
    } else {
        Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
    }
}

@Override
protected void onResume() {
    super.onResume();
    mGoogleApiClient.connect();
}

@Override
protected void onPause() {
    super.onPause();
    if (mGoogleApiClient.isConnected()) {
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        mGoogleApiClient.disconnect();
    }
}

@Override
public void onLocationChanged(Location location) {
    handleNewLocation(location);
}

public LatLng handleNewLocation(Location location) {
    Log.d(TAG, location.toString());
    double currentLatitude = location.getLatitude();
    double currentLongitude = location.getLongitude();
    latLng = new LatLng(currentLatitude,currentLongitude);
    MarkerOptions options = new MarkerOptions()
            .position(latLng)
            .title("You are here!");
    options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
    mMap.addMarker(options);
    mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
    return latLng;
}

public void startClick(View view) {
    showStopButton();
    if(stopped){
        startTime = System.currentTimeMillis() - elapsedTime;
    }
    else{
        startTime = System.currentTimeMillis();
    }
    Handler.removeCallbacks(startTimer);
    Handler.postDelayed(startTimer, 0);
    h1.removeCallbacks(startCalorieTracker);
    h1.postDelayed(startCalorieTracker,0);
    latLngStart = new LatLng (latLng.latitude,latLng.longitude);
}

public void stopClick(View view) {
    Double lat1 = latLngStart.latitude;
    Double lon1 = latLngStart.longitude;
    Double lat2 = latLng.latitude;
    Double lon2 = latLng.longitude;
    getDistance(lat1, lon1, lat2, lon2);
    hideStopButton();
    Handler.removeCallbacks(startTimer);
    h1.removeCallbacks(startCalorieTracker);
    stopped = true;
    ((TextView)findViewById(R.id.distance)).setText(dist);
    if (hrs > 0 || mins > 0 || secs >0) {
        Speed = dist/(Integer.parseInt(hours)+(Integer.parseInt(minutes)/60)+(Integer.parseInt(seconds)/3600));
        ((TextView)findViewById(R.id.speed)).setText(Speed + "km/h");
    }
    else {
        ((TextView)findViewById(R.id.speed)).setText("0 km/h");
    }
}

public void resetClick(View view) {
    stopped = false;
    ((TextView)findViewById(R.id.time)).setText("00:00:00");
    ((TextView)findViewById(R.id.distance)).setText("0 km");
    ((TextView)findViewById(R.id.speed)).setText("0 km/h");
    ((TextView)findViewById(R.id.calories)).setText("0 Cal");
}

public int getDistance(double lat1, double lon1, double lat2, double lon2) {
    double latA = Math.toRadians(lat1);
    double lonA = Math.toRadians(lon1);
    double latB = Math.toRadians(lat2);
    double lonB = Math.toRadians(lon2);
    double cosAng = (Math.cos(latA) * Math.cos(latB) * Math.cos(lonB - lonA)) +
            (Math.sin(latA) * Math.sin(latB));
    double ang = Math.acos(cosAng);
    double dist = ang * 6371;
    return (int) dist;
}

private void showStopButton(){
    findViewById(R.id.buttonStart).setVisibility(View.GONE);
    findViewById(R.id.buttonReset).setVisibility(View.GONE);
    findViewById(R.id.buttonStop).setVisibility(View.VISIBLE);
}

private void hideStopButton(){
    findViewById(R.id.buttonStart).setVisibility(View.VISIBLE);
    findViewById(R.id.buttonReset).setVisibility(View.VISIBLE);
    findViewById(R.id.buttonStop).setVisibility(View.GONE);
}

//Timer
private Runnable startTimer = new Runnable() {
    public void run() {
        elapsedTime = System.currentTimeMillis() - startTime;
        updateTimer(elapsedTime);
        Handler.postDelayed(this,REFRESH_RATE);
    }
};

private void updateTimer (float time){
    secs = (long)(time/1000);
    mins = (long)((time/1000)/60);
    hrs = (long)(((time/1000)/60)/60);

    secs = secs % 60;
    seconds=String.valueOf(secs);
    if(secs == 0){
        seconds = "00";
    }
    if(secs <10 && secs > 0){
        seconds = "0"+seconds;
    }

    mins = mins % 60;
    minutes=String.valueOf(mins);
    if(mins == 0){
        minutes = "00";
    }
    if(mins <10 && mins > 0){
        minutes = "0"+minutes;
    }

    hours=String.valueOf(hrs);
    if(hrs == 0){
        hours = "00";
    }
    if(hrs <10 && hrs > 0){
        hours = "0"+hours;
    }

    ((TextView)findViewById(R.id.time)).setText(hours + ":" + minutes + ":" + seconds);
}

public Handler h1= new Handler ();
public Runnable startCalorieTracker = new Runnable () {

    @Override
    public void run() {
        h1.postDelayed(this, REFRESH_RATE);
        int CaloriesBurnt = dist*85;
        ((TextView)findViewById(R.id.calories)).setText(CaloriesBurnt + "Cal");
    }
};

我得到的错误:

FATAL EXCEPTION: main
                                                                   Process: rainbow.com.fitnessapp3, PID: 3268
                                                                   java.lang.IllegalStateException: Could not execute method for android:onClick
                                                                       at android.view.View$DeclaredOnClickListener.onClick(View.java:4452)
                                                                       at android.view.View.performClick(View.java:5198)
                                                                       at android.view.View$PerformClick.run(View.java:21147)
                                                                       at android.os.Handler.handleCallback(Handler.java:739)
                                                                       at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                       at android.os.Looper.loop(Looper.java:148)
                                                                       at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                    Caused by: java.lang.reflect.InvocationTargetException
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)
                                                                       at android.view.View.performClick(View.java:5198) 
                                                                       at android.view.View$PerformClick.run(View.java:21147) 
                                                                       at android.os.Handler.handleCallback(Handler.java:739) 
                                                                       at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                       at android.os.Looper.loop(Looper.java:148) 
                                                                       at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
                                                                    Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x0
                                                                       at android.content.res.Resources.getText(Resources.java:312)
                                                                       at android.widget.TextView.setText(TextView.java:4417)
                                                                       at rainbow.com.fitnessapp3.MapsActivity.stopClick(MapsActivity.java:175)
                                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                                       at android.view.View$DeclaredOnClickListener.onClick(View.java:4447) 
                                                                       at android.view.View.performClick(View.java:5198) 
                                                                       at android.view.View$PerformClick.run(View.java:21147) 
                                                                       at android.os.Handler.handleCallback(Handler.java:739) 
                                                                       at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                       at android.os.Looper.loop(Looper.java:148) 
                                                                       at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

我认为问题在于以下几行代码:

public void startClick(View view) {
    showStopButton();
    if(stopped){
        startTime = System.currentTimeMillis() - elapsedTime;
    }
    else{
        startTime = System.currentTimeMillis();
    }
    Handler.removeCallbacks(startTimer);
    Handler.postDelayed(startTimer, 0);
    h1.removeCallbacks(startCalorieTracker);
    h1.postDelayed(startCalorieTracker,0);
    latLngStart = new LatLng (latLng.latitude,latLng.longitude);
}

public void stopClick(View view) {
    Double lat1 = latLngStart.latitude;
    Double lon1 = latLngStart.longitude;
    Double lat2 = latLng.latitude;
    Double lon2 = latLng.longitude;
    getDistance(lat1, lon1, lat2, lon2);
    hideStopButton();
    Handler.removeCallbacks(startTimer);
    h1.removeCallbacks(startCalorieTracker);
    stopped = true;
    ((TextView)findViewById(R.id.distance)).setText(dist);
    if (hrs > 0 || mins > 0 || secs >0) {
        Speed = dist/(Integer.parseInt(hours)+(Integer.parseInt(minutes)/60)+(Integer.parseInt(seconds)/3600));
        ((TextView)findViewById(R.id.speed)).setText(Speed + "km/h");
    }
    else {
        ((TextView)findViewById(R.id.speed)).setText("0 km/h");
    }
}

1 个答案:

答案 0 :(得分:1)

问题在于:

public void handleNewLocation(位置位置)

您的方法无效,因此,在执行时不会返回任何值。

最简单的解决方案是使用 Pair 对象,返回两个值,如下所示:

public Pair<String, String> handleNewLocation(Location location){
//do your thing here
[...]
Pair<String, String> pair = new Pair<>();
pair.first = Double.toString(currentLatitude);
pair.second = Double.toString(currentLongitude);
return pair;
}

然后,当您需要使用该方法时,请使用它:

Pair pair = handleNewLocation(Location location);
String firstValue = pair.first; //THIS IS THE FIRST VALUE
String secondValue = pair.second; //THIS IS THE SECOND VALUE

另一种方法是创建一个自定义对象,一个&#34; POJO&#34;,它将保存您的值。查看如何创建POJO,它是有趣的,有用的,并且很好地了解您是否想要进入Java编程。

另请注意,您不应该制作自己的方法&#34; public&#34;除非你需要。如果您只在写入的类中使用该方法,则可以将其设置为“私有”#34;。这是一个很好的做法,以确保您的应用程序是安全和受保护的。