我在服务中做错了什么?

时间:2012-02-16 20:28:27

标签: java android android-service

这是我第一次尝试创建服务并将其合并到我的应用程序中。出于某种原因,我无法调用任何公共方法(对于该位置)。

活动

public class MileageActivityV2 extends Activity {
    MileageService mService;
    Boolean mBound;

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

    @Override
    protected void onStart() {
    super.onStart();

    // bind to MileageService
    Intent intent = new Intent(this, MileageService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

    mService.getCurrentLocation();
    }

    @Override
    protected void onStop() {
    super.onStop();

    // unbind from the service
    if (mBound) {
        unbindService(mConnection);
        mBound = false;
    }
    }

    private ServiceConnection mConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName className, IBinder service) {
        // get the MileageService instance
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
    };
}

服务

public class MileageService extends Service implements IMileageService{

    private final IBinder binder = new LocalBinder();
    private List<Location> allLocations;
    private Location startLocation;
    private Location lastLocation;
    private Location currentLocation;
    private float totalDistance = 0;
    NotificationManager nMgr;

    /**
     * Class used for the client Binder. Since we know this service always runs
     * in the same process as the clients, dealing with IPC is not necessary.
     */
    public class LocalBinder extends Binder {
    public MileageService getService() {
        // return this instance of MileageService so clients can call public methods
        return MileageService.this;
    }
    }

    @Override
    public void onCreate() {
    nMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

    // display a notification about the service starting
    showNotification();
    }

    @Override
    public void onDestroy() {
    // cancel the persistent notification
    nMgr.cancel(R.string.mileage_service_started);

    // tell the user we stopped
    Toast.makeText(this, R.string.mileage_service_stopped, Toast.LENGTH_SHORT).show();
    }

    @Override
    public IBinder onBind(Intent intent) {
    return binder;
    }

    /**
     * Show a notification while this service is running.
     */
    private void showNotification() {
    // In this sample, we'll use the same text for the ticker and the
    // expanded notification
    CharSequence text = getText(R.string.mileage_service_started);

    // Set the icon, scrolling text and timestamp
    Notification notification = new Notification(R.drawable.car_1, text, System.currentTimeMillis());

    // The PendingIntent to launch our activity if the user selects this
    // notification
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MileageActivity.class), 0);

    // Set the info for the views that show in the notification panel.
    notification.setLatestEventInfo(this, getText(R.string.mileage_service_started), text, contentIntent);

    // Send the notification.
    // We use a string id because it is a unique number. We use it later to
    // cancel.
    nMgr.notify(R.string.mileage_service_started, notification);
    }

    private static final int BUMP_MSG = 1;

    private Handler mHandler = new Handler() {

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case BUMP_MSG:
        break;
        default:
        super.handleMessage(msg);
        }
    }
    };

    @Override
    public List<Location> getLocations() {
    return this.allLocations;
    }

    @Override
    public Location getCurrentLocation() {
    return this.currentLocation;
    }

    @Override
    public Location getStartLocation() {
    return this.startLocation;
    }

    @Override
    public Location getLastLocation() {
    return this.lastLocation;
    }

    @Override
    public Float getDistance() {
    return this.totalDistance;
    }
}

2 个答案:

答案 0 :(得分:2)

您的问题是,在您的onStart方法中,您的服务实际上尚未启动。电话

Intent intent = new Intent(this, MileageService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

是异步的。在调用任何方法之前,您需要等待服务绑定。有很多方法可以做到这一点,但最快的方法是将调用mService.getCurrentLocation();添加到onServiceConnected方法的末尾。请注意,这将在应用程序的主线程上运行,因此不要对其执行阻止操作。

随着您的进一步发展,您可能会发现需要从连接结束时启动异步任务,以执行您想要的所有工作而不会影响ui。网络上有这样的例子。

答案 1 :(得分:-1)

除了我的UI线程之外,你不应该调用UI方法来处理来自其他线程的UI。而你的服务肯定不是ibn UI线程。如果您想从服务线程修改UI,则必须将异步任务发布到UI线程。例如:

http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable