简体   繁体   中英

Passing large objects between activities through eventbus android

I am new to EventBus . I want to pass the byteArray to the next activity, I don't want to use intents because the byteArray is large i will end up in out of memory error. I want to pass it through eventbus .

While implementing event bus, I am getting an exception saying No subscribers registered for event class com.saikirans.eventbuspractise.MessageEvent .

Thanks in advance.

MainActivity class:

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 class:

public class MessageEvent {
  public final String message;

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

You don't receive the Event because ReceiverActivity haven't registered as EventBus subscriber. It's because when you launching the ReceiverActivity via intent in this code:

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!"));
   }
});

your ReceiverActivity still in onCreate() state. But it register itself in onStart() state:

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

So you send message Event before ReceiverActivy ready to accept.


Solution

A simple solution is to inform the MainActivity when ReceiverActivity ready to receive the message. When you ReceiverActivity has been created send a message Event.

First create an Event that tell ReceiverActivity is ready:

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

in ReceiverActivity onCreate() or onStart() send the message:

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

Then in your MainActivity, when you receive the ReceiverReadyEvent (ReceiverActivity is created) send the 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!"));
  }
}

UPDATE

For everyone who got error:

No subscribers registered for event class com. .

Eventhough has register and unregister EventBus with the following code:

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

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

This is because the Activity which should be receiving the message is not on the foreground. When activity is behind another activity, it will call its onStop() method. So we end doing Unregistering EventBus.

To overcome the problem, we should register EventBus in onCreate() and unregister in 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);
}

It will unregister EventBus only when we finishing the activity.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM