Как передать контекст из деятельности в службу - PullRequest
0 голосов
/ 14 апреля 2019

У меня проблема, мне нужен доступ к просмотрам в деятельности из службы. Я подумал, что хороший способ сделать это - передать контекст действия, а затем использовать его для доступа к представлениям. Тем не менее, когда я запускаю его, он выдает нулевую ошибку, означая, что объект (представление) является нулевым. Это код, я хотел бы знать, как это исправить:

public class Purchase extends AppCompatActivity {
   private TextView purchaseAmount;
   private Button but;

   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_purchase);
      but = (Button) findViewById(R.id.makePurBut);
      purchaseAmount = (TextView) findViewById(R.id.purchaseAmout);
      Intent i = new Intent(Purchase.this, MyHostApduService.class);
      MyHostApduService myHostApduService = new MyHostApduService(Purchase.this);
      startService(i);
  }
}


public class MyHostApduService extends HostApduService {
static Context context;
   public MyHostApduService(Context context)
   {
      this.context = context;
   }

   public int onStartCommand(Intent intent, int flags, int startId) {
      textView = (TextView)((Activity)context).findViewById(R.id.purchaseAmout);
      but = (Button)((Activity)context).findViewById(R.id.makePurBut);
      return flags;
  }
}

Ответы [ 2 ]

2 голосов
/ 14 апреля 2019

Service имеет собственный контекст и не может напрямую взаимодействовать с пользовательским интерфейсом.

Но вы можете создать связанный сервис или использовать ResultReceiver. Вот варианты, описанные, например, здесь: https://medium.com/@ankit_aggarwal/ways-to-communicate-between-activity-and-service-6a8f07275297

Например, чтобы создать связанную службу, как показано в примере:

  1. Добавить интерфейс слушателя:
interface Callback {
  void sendMes(Object payload); // or more specific signature
}
  1. В эксплуатации:
    private final IBinder mBinder = new LocalBinder();

    public class LocalBinder extends Binder {
        List<Callback> listeners;

        LocalService getService() {
            return LocalService.this;
        }
        void addListener(Callback listener) {
             listeners.add(listener);
        }
        void removeListener(Callback listener) {
             listeners.remove(listener);
        }
    } 
  1. В действии (которое реализует Callback):
private LocalService mBoundService;
private LocalService.LocalBinder mBinder;

private ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
        mBinder = ((LocalService.LocalBinder)service);
        mBoundService = ((LocalService.LocalBinder)service).getService();
        ((LocalService.LocalBinder).addListener(MyActivity.this);
    }

    public void onServiceDisconnected(ComponentName className) {
        mBoundService = null;
    } 
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    bindService(new Intent(MyActivity.this, LocalService.class),
                mConnection,
                Context.BIND_AUTO_CREATE);
    mIsBound = true;
}

@Overrride 
public void sendMes(Object payload) { ... }

@Override
protected void onDestroy() {  
 super.onDestroy(); 
 if (mIsBound) {
        mBinder.removeListener(this);
        unbindService(mConnection);
        mIsBound = false;
    }
}
1 голос
/ 14 апреля 2019

Самый простой способ решить вашу проблему - использовать LocalBroadcastManager .

Отправьте трансляцию из Сервиса в Активность, затем в onReceive вы можете управлять своими представлениями в самой Активности.

Обязательно зарегистрируйте / отмените регистрацию получателя в onStart / onPause вместо onCreate / onDestroy, как внутри ссылки.

...