有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法在服务中使用findViewById,使用了LayoutInflater但没有帮助,未显示任何值

我开发了一个计算足迹的应用程序,我希望它能够在后台工作[服务] 使用此处提到的服务时findViewbyId存在问题:

Android findViewById in service

我尝试过这种方法,但值总是0,我做错了什么

这是我的主要活动课:

public class MainActivity extends AppCompatActivity {
private  final int PHYISCAL_ACTIVITY = 0;
private Button btnStopService;
private Button btnStartService;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_DENIED) {
        //ask for permission
        requestPermissions(new String[]{Manifest.permission.ACTIVITY_RECOGNITION}, PHYISCAL_ACTIVITY);
    }
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    btnStartService =  findViewById(R.id.btnStartService);
    btnStopService = findViewById(R.id.btnStopService);
    initButtonsOnClick();
}

private void initButtonsOnClick() {
    OnClickListener listener = new OnClickListener() {
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btnStartService:
                    startMyService();
                    break;
                case R.id.btnStopService:
                    stopMyService();
                    break;
                default:
                    break;
            }
        }
    };
    btnStartService.setOnClickListener(listener);
    btnStopService.setOnClickListener(listener);
}

private void startMyService() {
    Intent serviceIntent = new Intent(this, MyService.class);
    startService(serviceIntent);
}

private void stopMyService() {
    Intent serviceIntent = new Intent(this, MyService.class);
    stopService(serviceIntent);
}}

这是我的服务课:

public class MyService extends Service implements SensorEventListener {
private Toast toast;
private Timer timer;
private TimerTask timerTask;
private SensorManager sensorManager;
private Sensor mineSensor;
int Steps;

private TextView textView;

@Override
public void onSensorChanged(SensorEvent sensorEvent) {
    if (sensorEvent.sensor == mineSensor) {
        Steps= (int) sensorEvent.values[0];
        textView.setText(String.valueOf(Steps));
    }
}

@Override
public void onAccuracyChanged(Sensor sensor, int i) {

}

private class MyTimerTask extends TimerTask {
    @Override
    public void run() {
        showToast("Your service is still working");
    }
}

private void showToast(String text) {
    toast.setText(text);
    toast.show();
}

private void writeToLogs(String message) {
    Log.d("HelloServices", message);
}

@Override
public void onCreate() {
    super.onCreate();
    writeToLogs("Called onCreate() method.");
    timer = new Timer();
    toast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    writeToLogs("Called onStartCommand() methond");
    clearTimerSchedule();
    initTask();
    timer.scheduleAtFixedRate(timerTask, 4 * 1000, 4 * 1000);
    showToast("Your service has been started");
    return super.onStartCommand(intent, flags, startId);
}

private void clearTimerSchedule() {
    if(timerTask != null) {
        timerTask.cancel();
        timer.purge();
    }
}

private void initTask() {
    timerTask = new MyTimerTask();
    LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    View layout = inflater.inflate(R.layout.activity_main, null);
    textView = (TextView) layout.findViewById(R.id.image);
    sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    if (sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER) != null) {
        mineSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);

    } else {

        textView.setText("No Sensor ");

    }
}

@Override
public void onDestroy() {
    writeToLogs("Called onDestroy() method");
    clearTimerSchedule();
    showToast("Your service has been stopped");
    super.onDestroy();
}

@Override
public IBinder onBind(Intent arg0) {
    return null;
}}

共 (2) 个答案

  1. # 1 楼答案

    您需要在主活动中注册广播接收器,才能从以下服务中获得价值:

    private BroadcastReceiver broadcastReceiver;
    
    if(broadcastReceiver == null){
                        broadcastReceiver = new BroadcastReceiver() {
                            @Override
                            public void onReceive(Context context, Intent intent) {
                                // here you get the values from service 
                    //get values from intent and set it to your layout
    
                            }
                        };
    registerReceiver(broadcastReceiver,new IntentFilter("my_reciever"));
                    Intent i =new Intent(getApplicationContext(),yourservice.class);
                    startService(i);
                       
                    }
                   
    

    服务级别:

    Intent i = new Intent("my_reciever");
                    i.putExtra("myvalues",yourvalues);
                    sendBroadcast(i);
        
                    
          
    
  2. # 2 楼答案

    我认为一个简单的解决方案(但可能不是更好)是创建一个带有实时数据字段的单例(例如DataController)。 在应用程序类内创建此控制器,然后从服务中创建过去的值,并在活动中观察

        public final class DataController {
    
        private static volatile DataController instance;
        private static final Object lock = new Object();
    
        private MutableLiveData<Integer> counter = new MutableLiveData(0);
        private MutableLiveData<String> message = new MutableLiveData();
    
        public static DataController get() {
            if (instance == null) {
                synchronized (lock) {
                    if (instance == null) {
                        instance = new DataController();
                    }
                }
            }
            return instance;
        }
        
        public void setCounter(Integer count){
            counter.postValue(count);
        }
        
        public void setMessage(String str){
            message.postValue(str);
        }
    
        public MutableLiveData<Integer> getCounter() {
            return counter;
        }
    
        public MutableLiveData<String> getMessage() {
            return message;
        }
    }