【问题标题】:Unable to perform work on the background thread无法在后台线程上执行工作
【发布时间】:2020-05-21 01:11:02
【问题描述】:

所以,我正在关注 this tutorial 在我的应用程序中实现服务。我成功实施了服务。服务启动,通知正常显示。一切都很好,只是我无法在后台线程上工作。请看下文。

我的目标是设置一个模拟位置。

这是我的onStartCommand 我的服务:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {



    Intent notificationIntent = new Intent(this, MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,
            0, notificationIntent, 0);

    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Example Service")
            .setContentText("hi")
            .setSmallIcon(R.drawable.icon)
            .setContentIntent(pendingIntent)
            .build();


    startForeground(1, notification);

    //do work on a background thread
    new Thread(new Runnable() {
        @Override
        public void run() {

            startMockLocation(); // doesn't actually mock device's location!
        }
    }).start();

    return START_NOT_STICKY;
}

但是,当我这样做时,它工作正常,但效率不高:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {



    Intent notificationIntent = new Intent(this, MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,
            0, notificationIntent, 0);

    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Example Service")
            .setContentText("hi")
            .setSmallIcon(R.drawable.icon)
            .setContentIntent(pendingIntent)
            .build();


    startForeground(1, notification);

// works great
timer.schedule(new TimerTask() {
    @Override
    public void run() {

        startMockLocation();
        //other stuff
    }
}, 0, 1000);

    return START_NOT_STICKY;
}

模拟定位方式:

public void startMockLocation(){ // this code is fine, nothing to fix here, something is wrong with the thread though :(

    FusedLocationProviderClient locationProvider =  new FusedLocationProviderClient(getApplicationContext());
    locationProvider.setMockMode(true);

    Location loc = new Location("gps");

    Location mockLocation = new Location("gps"); // a string
    mockLocation.setLatitude(48.8566);
    mockLocation.setLongitude(2.3522);
    mockLocation.setAltitude(loc.getAltitude());
    mockLocation.setTime(System.currentTimeMillis());

    mockLocation.setAccuracy(1f);
    mockLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        mockLocation.setBearingAccuracyDegrees(0.1f);
        mockLocation.setVerticalAccuracyMeters(0.1f);
        mockLocation.setSpeedAccuracyMetersPerSecond(0.01f);
    }
    locationProvider.setMockLocation(mockLocation);

}

【问题讨论】:

  • 有什么问题?
  • @Mr.AF 我无法从onStartCommand 内部设置模拟位置。但是,它在 Main Activity 上正常工作。
  • 你知道所有的方法都被正确调用了吗?将日志放入runstartMockLocation 会发生什么?

标签: java android multithreading


【解决方案1】:

如果无法从后台线程执行工作,则意味着您看不到 startMockLocation() 的效果,这取决于是否有任何依赖于 startMockLocation() 的计算。如果您不加入线程或在某处阻塞并等待后台线程完成,那么您的主线程很可能会在后台线程完成其工作之前运行直到终止。那看起来你的后台线程没有做任何事情。

【讨论】:

  • 是的。没错,我看不到startMockLocation的效果。你能用一些代码来支持你的答案吗?然后我会继续接受你的回答。
  • 所以当你在主线程上执行 startMockLocation() 时,一切正常吗?如果它在按顺序执行时运行良好,您是否可以尝试从 startMockLocation() 打印一条消息以查看代码是否到达?
  • 代码甚至在线程上到达。 但在线程中,startMockLocation 不会像通常那样模拟设备的位置
  • 像往常一样?你的意思是当你把 startMockLocation() 放在主线程上时,它工作正常吗?也许这个stackoverflow.com/questions/51445821/… 是怎么回事?
  • 你的意思是当你把 startMockLocation() 放在主线程上时,它工作正常? 是的,这就是我的意思。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多