如何将上下文从活动传递到服务

时间:2019-04-14 20:02:39

标签: android android-activity android-service android-context

我遇到问题,我需要从服务访问活动中的视图。我认为这样做的一个好方法是传递活动上下文,然后使用它来访问视图。但是,当我运行它时,它将引发null错误,这意味着对象(视图)为null。这是代码,我想知道如何解决这个问题:

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 个答案:

答案 0 :(得分:2)

Service具有自己的上下文,并且不能直接与UI交互。

但是您可以创建绑定服务或使用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 :(得分:1)

解决问题的最简单方法是访问use LocalBroadcastManager

将广播从“服务”发送到“活动”,然后在onReceive中可以在“活动”本身中操纵视图。

请确保在onStart / onPause中注册/注销接收者,而不要像内部链接那样注册onCreate / onDestroy。