繁体   English   中英

我在服务中做错了什么?

[英]What am I doing wrong in my 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;
    }
}

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

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

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

随着您的前进,您可能会发现需要从连接结束处启动一个异步任务,以完成所需的所有工作而不影响ui。 网上有一些例子。

您不应从我的UI线程之外的其他线程中调用处理UI的UI方法。 而且您的服务当然不是ibn UI线程。 如果要从服务线程修改UI,则必须将异步任务发布到UI线程。 例如:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM