通过eventbus android在活动之间传递大对象

时间:2016-06-09 09:57:01

标签: android greenrobot-eventbus

我是EventBus的新手。我想将byteArray传递给下一个活动,我不想使用意图,因为byteArray很大,我将最终出现内存不足错误。我希望通过eventbus传递它。

在实施事件总线时,我收到一个例外情况No subscribers registered for event class com.saikirans.eventbuspractise.MessageEvent

提前致谢。

MainActivity类:

public class MainActivity extends AppCompatActivity {
  Intent intent;
  Button button;
  byte[] byteArray;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    button = (Button) findViewById(R.id.button);
    Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.screen);
    intent = new Intent(this, ReceiverActivity.class);
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bm.compress(Bitmap.CompressFormat.PNG, 100, stream);
    byteArray = stream.toByteArray();
    intent.putExtra("bitmap", byteArray);

    button.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        startActivity(intent);
        EventBus.getDefault().post(new MessageEvent("Hello everyone!"));
      }
    });
  }
}

ReceiverActivity .class

public class ReceiverActivity extends AppCompatActivity {
  ImageView imageView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_reciver);
    byte[] byteArray = getIntent().getByteArrayExtra("bitmap");
    Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
    imageView = (ImageView) findViewById(R.id.imageView);
    assert imageView != null;
    imageView.setImageBitmap(bitmap);
  }

  // This method will be called when a MessageEvent is posted
  @Subscribe
  public void onMessageEvent(MessageEvent event){
    Toast.makeText(this, event.message, Toast.LENGTH_SHORT).show();
  }

  @Override
  public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
  }

  @Override
  public void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
  }
}

MessageEvent类:

public class MessageEvent {
  public final String message;

  public MessageEvent(String message) {
    this.message = message;
  }
}

1 个答案:

答案 0 :(得分:3)

您没有收到该活动,因为ReceiverActivity尚未注册为EventBus订阅者。这是因为当您在此代码中通过意图启动ReceiverActivity时:

button.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
     startActivity(intent); // Here you start the intent.
     EventBus.getDefault().post(new MessageEvent("Hello everyone!"));
   }
});

您的ReceiverActivity仍在onCreate()州。但它在onStart()状态中注册自己:

@Override
public void onStart() {
  super.onStart();
  EventBus.getDefault().register(this);
}

所以你在ReceiverActivy准备接受之前发送消息事件。

解决方案

一个简单的解决方案是在MainActivity准备好接收消息时通知ReceiverActivity。创建ReceiverActivity后,发送消息Event。

首先创建一个告诉ReceiverActivity准备就绪的事件:

public class ReceiverReadyEvent() {
  public ReceiverReadyEvent();
}

在ReceiverActivity onCreate()或onStart()中发送消息:

public class ReceiverActivity extends AppCompatActivity {
  ...
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    EventBus.getDefault().post(new ReceiverReadyEvent());
  }
}

然后在您的MainActivity中,当您收到ReceiverReadyEvent(创建ReceiverActivity)时,请发送MessageEvent

public class MainActivity extends AppCompatActivity {
  // This method will be called when ReceiverActivity is ready to receive MessageEvent
  @Subscribe
  public void onMessageEvent(ReceiverReadyEvent event){
    // Send message to ReceiverActivity.
    EventBus.getDefault().post(new MessageEvent("Hello everyone!"));
  }
}

更新

对于遇到错误的每个人:

  

没有订阅者注册参加活动课程。

尽管已经使用以下代码注册和取消注册EventBus:

@Override
public void onStart() {
  super.onStart();
  EventBus.getDefault().register(this);
}

@Override
public void onStop() {
  EventBus.getDefault().unregister(this);
  super.onStop();
}

这是因为应该接收消息的Activity不在前台。当活动落后于另一个活动时,它将调用其onStop()方法。所以我们结束了取消注册EventBus。

要解决这个问题,我们应该在onCreate()中注册EventBus并在onDestroy()中取消注册:

// Registering
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  ...
  EventBus.getDefault().post(new ReceiverReadyEvent());
}

// Unregistering
@Override
public void onDestroy() {
  super.onDestroy();
  EventBus.getDefault().unregister(this);
}

只有在我们完成活动时才会取消注册EventBus。