Вопрос

As a N00bie to android, I'm trying to build a simple map-app. I started out doing everything in the same class, but for obvious reasons that got out of hand, fast. So I wanted to split the class, with the base class as the main flow for the activity, and the subclass as the 'utility' class.

So I instantiate an Subclass object, and in the subclass's onCreate I start calling methods. These methods never run though. What am I doing wrong? As soon as I create the subclass object, the sub's onCreate should fire, no? And, is it even the smart way of doing this in a subclass, instead of a whole other class?

Thanks in advance!

Base class:

package com.example.TestMap;

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;

public class MyActivity extends Activity  {

    private GoogleMap mMap;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        LocationClass locationClass = new LocationClass();



    }

    public void setMap(){
        Log.i("TestMap", "setMap");
        mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
        mMap.setMyLocationEnabled(true);

    }



    public void setCamera(Location location) {

        Log.i("TestMap", "setCamera");

        final LatLng locationLatLng = new LatLng( (location.getLatitude() ), location.getLongitude() );


        CameraPosition cameraPosition = new CameraPosition.Builder()
                .target(locationLatLng)      // Sets the center of the map to Mountain View
                .zoom(17)                   // Sets the zoom
                .bearing(90)                // Sets the orientation of the camera to east
                .tilt(30)                   // Sets the tilt of the camera to 30 degrees
                .build();                   // Creates a CameraPosition from the builder

        mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
    }

}

Subclass

package com.example.TestMap;

import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import java.util.List;


public class LocationClass extends MyActivity implements LocationListener {

    private LocationManager locationManager;
    private String provider;
    private List<String> providers;


    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i("TestMap", "LocationClass OnCreate");
        GetProivder();
    }


    public void GetProivder (){
        Log.i("TestMap", "LocationClass GetProivder");


        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        Criteria criteria = new Criteria();
        criteria.setAccuracy(2);
        provider = locationManager.getBestProvider(criteria, false);
        providers = locationManager.getProviders(true);

        Location location = locationManager.getLastKnownLocation(provider);

        Log.i("TestMap", "providerlist = " + providers);
        Log.i("TestMap", "getBestProvider = " + provider);
        Log.i("TestMap", "Location = " + location);

        if (location != null) {
            Log.i("TestMap", "Provider " + provider + " has been selected.");
            super.setCamera(location);
            super.setMap();

        } else {
            Log.i("TestMap", "location is null.");

        }
    }


    @Override
    public void onLocationChanged(Location location) {
        Log.i("TestMap", "onLocationChanged");
    }

    @Override
    protected void onResume() {
        super.onResume();
        locationManager.requestLocationUpdates(provider, 400, 1, this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        locationManager.removeUpdates(this);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        Log.i("TestMap", "onStatusChanged");
    }

    @Override
    public void onProviderEnabled(String provider) {
        Toast.makeText(this, "Enabled new provider " + provider,
                Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onProviderDisabled(String provider) {
        Log.i("TestMap", "onProviderDisabled");
        Toast.makeText(this, "Disabled provider " + provider,
                Toast.LENGTH_SHORT).show();
    }


}
Это было полезно?

Решение

Your code

LocationClass locationClass = new LocationClass(); does not create it. It just makes an object of it, but it does not tie to the lifecycle and call the methods.

You need to start it with an intent to make it appear (and take the entire screen based on skimming your code). Android will fire the appropriate method calls when you do so.

Like this:

Intent intent = new Intent(this, LocationClass.class);          
startActivity(intent);

More information can be found here: http://developer.android.com/training/basics/firstapp/starting-activity.html#StartActivity

It must be defined in your manifest too or it will crash. There are other noticeable oddities things in your code, do you want LocationClass to extend MyActivity and not Activity? Your LocationClass also does not call setContentView() in onCreate, so you're not going to see a UI (as far as I can tell), unless you wanted it through the extends part.

EDIT : If you extend subclass and put this intent code in onCreate, you're probably going to crash, as it will call super() in MyActivity (calling onCreate() again as it's the superclass), and will keep making more intents to start the activity. You should not subclass MyActivity if that's what the 'parent' class is.

You should only subclass Activity or a global parent activity (e.g. in my project right now, I extend SpiceActivity, as they all use common components related to Spice).

Другие советы

The subclass' onCreate method should be called when it is created by Android (see Understanding the Lifecycle Callbacks), which for example happens when an Intent to that Activity is issued.

Edit: I just saw @Mgamerz answer and realised that line in your superclass Activity was where you were trying to make Android create the subclass Activity. This next paragraph is somewhat irrelevant now, but note that you do still need to add the subclass activity to the manifest file.

Are you sure you're application is actually starting the subclass Activity, or is it still starting the superclass Activity? You might have to have a look at your project's "AndroidManifest.xml" file and check that there's an <activity /> element corresponding to the subclass Activity.


I think splitting the class into a superclass and a subclass is sensible if the superclass has functionality which can/will be re-used by multiple subclass Activities. For example you might have subclass activities like DirectionsActivity and SearchActivity which have some common map-related activity provided by their superclass MapActivity. Even if you have only one subclass Acitivty now, it may still make sense to have a superclass and a subclass if you think you're likely to write additional map-related activities later on. I my opinion it's not sensible to split the class into a superclass and a subclass just because the single class was getting too long. If you do just want a helper class and you don't expect to have more MapActivity subclasses in the future, you could make a MapUtils class in the same package as the Activity class, which would define some static helper methods. For example, you could put your GetProvider method into such a helper class. Sketch example (note the package-private access of MapHelper):

class MapHelper {

    static Location getProvider() {
        // ...
        return location;
    }

    // Other helper methods here
}

public class MyActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // ...
        setCamera(MapHelper.getProvider());
        setMap();
    }

    // Other activity methods here
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top