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

Posted

技术标签:

【中文标题】如何将上下文从活动传递到服务【英文标题】:How to pass context from activity to service 【发布时间】:2019-09-04 20:46:10 【问题描述】:

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

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;
  

【问题讨论】:

What is a NullPointerException, and how do I fix it?的可能重复 我很惊讶 android 甚至允许您在这样的嵌套类中创建服务 - 您能够在清单中声明它吗? 【参考方案1】:

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

但您可以创建绑定服务或使用ResultReceiver。例如,此处描述的选项:https://medium.com/@ankit_aggarwal/ways-to-communicate-between-activity-and-service-6a8f07275297

例如创建绑定服务,如示例所示:

    添加监听接口:
interface Callback 
  void sendMes(Object payload); // or more specific signature

    在役:
    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);
        
     
    在活动中(实现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;
    

【讨论】:

【参考方案2】:

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

从 Service 向 Activity 发送广播,然后在 onReceive 中您可以在 Activity 本身中操作视图。

确保在 onStart/onPause 中注册/取消注册 Receiver,而不是像内部链接那样在 onCreate/onDestroy 中注册。

【讨论】:

以上是关于如何将上下文从活动传递到服务的主要内容,如果未能解决你的问题,请参考以下文章

如何将 traceId 从 gRPC 的上下文传递到另一个线程/线程池?

从活动传递数据到类扩展视图

将上下文从 Web 请求的控制器传递到数据库层

NextJS:通过上下文将字符串从输入传递到 getStaticProps

如何将我的程序添加到右键单击上下文菜单并传递它的路径

从纵向活动中以横向打开相机时上下文为空