Otto Subscribe method not called from Activity to Fragment in Another Activity - android

This is my first activity where Im making a post call. The bus provider is the default one in the otto sample app.
void openNextActivity()
{
manager.bus.post("Hi");
// Intent to my next Activity
}
This is my fragment in another activity where im subscribing for the data. The bus received is the same, however the subscribe method is not being called.
public class ProductListFragment extends BaseFragment {
String LOG_TAG = ProductListFragment.class.getCanonicalName();
public static ProductListFragment newInstance() {
ProductListFragment fragment = new ProductListFragment();
return fragment;
}
public ProductListFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().invalidateOptionsMenu();
}
#Override
public void onResume() {
super.onResume();
BusProvider.getInstance().register(this);
}
#Override
public void onPause() {
super.onPause();
BusProvider.getInstance().unregister(this);
}
#Subscribe public void onPostRecived(String s) {
Log.d(LOG_TAG, s);
}
}
There are no errors on anything being received, however if I put a button onclick on the fragment and post some content from there, the subscribe method is being called. For eg.
#OnClick(R.id.makePostCall) void call() {
BusProvider.getInstance().post("Hi");
}
I'm getting the appropriate log on this call. Any idea where the code is going wrong?

it seems you subscribe your second activity's fragment after sending stuff to event bus. Consider changing your logic

u send msg before intent;the BusProvider id registered after intent;
just try:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
BusProvider.getInstance().post("Hi");
}
},3000);

Related

Get data from viewpager fragments

I have an Activity which has a Save details button and a Viewpager which contains 4 fragments. The Fragments contains User details form. Once the Save button is clicked I need to get the data from all fragments and save the details. How to get the data entered by the user in all 4 fragments when Save button is clicked in the activity?
I just worked on an app that had the same use case. In addition, I had to save the data on a back navigation as well. The problem was a bit more difficult that I though it should have been. The problems came from the fact that not all the fragments in the ViewPager are guaranteed to be alive. They either may not have been started yet, or destroyed when the user paged off of them.
To solve the problem, I took inspiration from this blog post about handing back-press events. I had to modify it a bit to allow for any fragments that may be running and not just one.
public abstract class BackHandledFragment extends Fragment {
protected BackHandlerInterface backHandlerInterface;
public abstract String getTagText();
public abstract boolean onBackPressed();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(!(getActivity() instanceof BackHandlerInterface)) {
throw new ClassCastException("Hosting activity must implement BackHandlerInterface");
} else {
backHandlerInterface = (BackHandlerInterface) getActivity();
}
}
#Override
public void onResume() {
super.onResume();
backHandlerInterface.addRunningFragment(this);
}
#Override
public void onPause() {
super.onPause();
backHandlerInterface.removeRunningFragment(this);
}
public interface BackHandlerInterface {
public void addRunningFragment(BackHandledFragment backHandledFragment);
public void removeRunningFragment(BackHandledFragment backHandledFragment);
}
}
The Activity implements the interface and tracks the active fragments:
public class EditActivity implements BackHandledFragment.BackHandlerInterface
{
private List<BackHandledFragment> listActiveFragments = new ArrayList<>
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Notify each active fragment that the back was pressed, this will allow
// them to save any data.
for (BackHandledFragment bf : listActiveFragments) {
bf.onBackPressed();
}
}
#Override
public void addRunningFragment(BackHandledFragment backHandledFragment) {
listActiveFragments.add(backHandledFragment);
}
#Override
public void removeRunningFragment(BackHandledFragment backHandledFragment) {
listActiveFragments.remove(backHandledFragment);
}();
}
Each fragment must extend BackHandledFragment:
public class DetailNetworkFragment extends BackHandledFragment {
#Override
public void onPause() {
super.onPause();
EventBus.getDefault().unregister(this);
saveDataFields();
}
#Override
public void onResume() {
super.onResume();
EventBus.getDefault().register(this);
}
#Override
public String getTagText() {
return TAG;
}
#Override
public boolean onBackPressed() {
saveDataFields();
return false;
}
}
The saveDataFields() is not too interesting. It just copies the data out of the UI views and saves them back to an object in the Activity.

Android get EventBus event on fragment not working

after define event class and post event on Activity onBackPressed() i cant get event on fragment, some my activities opening above this fragment which that is child of MainActivity. i want to get some events that post from other opening activitis, but my code doesnt get this event on Fragment, but i can post event from Activity onBackPressed()
SignalActivityMarketDetailStateEvents class:
public class SignalActivityMarketDetailStateEvents {
private boolean activityMarketDetailState;
public SignalActivityMarketDetailStateEvents(boolean activityMarketDetailState) {
this.activityMarketDetailState = activityMarketDetailState;
}
public boolean isActivityMarketDetailState() {
return activityMarketDetailState;
}
}
ActivitySecond :
#Override
public void onBackPressed() {
EventBus.getDefault().post(new SignalActivityMarketDetailStateEvents(true));
}
Fragment to get event:
#Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(SignalActivityMarketDetailStateEvents event) {
Log.e("EventBus ","Received");
}
#Override
public void onStart() {
EventBus.getDefault().register(this);
super.onStart();
}
#Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
#Override
public void onResume() {
EventBus.getDefault().register(this);
super.onResume();
}
in my Fragment this line doesnt work after post event:
Log.e("EventBus ","Received");
You are not mindful of the life cycle's of those activities. You could use the sticky events (postSticky) . Or update the state in some singleton and read that in onResume.

EventBus event between two fragments not fired

Problem: I am using EventBus by greenrobot to pass some events.
It is working for me unfortunately for the scenario of passing data between two fragments it does not. So the event does not get fired.
Question: Do I misunderstand the concept? Or is there a mistake in my code?
Note: Both Fragments exist at the time of sending the event. One fragment is the parent and the other one the child to display details.
detail fragment:
public class DetailFragment extends Fragment {
(...)
refreshButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
EventBus.getDefault().post(new IntentRefresh());
}
});
(...)
}
EventBus class:
public class IntentRefresh {
public IntentRefresh (){}
public void refreshParent() {
}
}
parent fragment:
public class ParentFragment extends Fragment {
(...)
#Override
public void onPause() {
super.onPause();
EventBus.getDefault().unregister(this);
}
#Override
public void onResume() {
super.onResume();
EventBus.getDefault().register(this);
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void updateList(IntentRefresh intentRefresh) {
Toast.makeText(getActivity(), "LUEEEEPT", Toast.LENGTH_SHORT).show();
}
(...)
}
The Fragment lifecycle is quite a bit more complicated than the Activity lifecycle. I would guess that your onResume() isn't being called how you think it is. I would recommend moving your registering and un registering to the onAttach() and onDetach() methods.
I use #CaseyB's answer. its working for me perfectly.Like below
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (!EventBus.getDefault().isRegistered(this))
EventBus.getDefault().register(this);
}
#Override
public void onDetach() {
super.onDetach();
EventBus.getDefault().unregister(this);
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(CallbackModel event) {
}

EventBus does not register event on new activity

I have implemented an otto bus example. It works fine, but ONLY on the second time I visit the activity.
For example, when I load the app and hit the secret message button I am taken to the activity but the toast does not show. Then I hit the back button to return to the MainActivity and hit the show secret message button again and when I am taken to the secret message activity the toast is displayed. I realize it works the second time because I have created a leak by not unregistering the event.
Is there something I am missing about the logic?
MainActivity:
public class MainActivity extends AppCompatActivity {
Button buttonSecretMessage;
Intent intentToMessage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentToMessage = new Intent(MainActivity.this, SecretMessageActivity.class);
buttonSecretMessage = (Button) findViewById(R.id.buttonSecretMessage);
buttonSecretMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EventBus.getInstance().post(new MakeMySecretMessageEvent());
startActivity(intentToMessage);
}
});
}
}
Secret Message Activity:
public class SecretMessageActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_secret_message);
}
#Subscribe
public void getMySecretMessage(MakeMySecretMessageEvent event){
Toast.makeText(this, event.getMessage(), Toast.LENGTH_SHORT).show();
}
#Override
protected void onStart(){
super.onStart();
EventBus.getInstance().register(this);
}
#Override
protected void onStop() {
super.onStop();
//EventBus.getInstance().unregister(this);
}
}
MakeMySecretMessageEvent:
public class MakeMySecretMessageEvent {
public MakeMySecretMessageEvent() {
}
public String getMessage() {
String message = "YOU ARE AWESOME!";
return message;
}
}
EventBus:
public final class EventBus extends Bus{
private static final EventBus Bus = new EventBus();
public static Bus getInstance() {
return Bus;
}
private EventBus() {
}
}
You can send sticky event using EventBus library. It allows you to send events to component which is not created yet.
You`ll find more info here.
Here EventBus has applied in wrong scenario, when you can simply send data via intent or bundle. Which is more reliable in communication with one activity with another. You will never ever receive event on first click, as event fire is instant and your activity creation will take some time accordingly.
So try to use bundle or intent to setup communication b/w to activity one after another.
Thanks to contributors I now have a better understanding of the activity life cycle and how it fits in with event bus. That is you cannot send an event from the MainActivity to its children, but the other way around instead. Below reflects how to implement an otto event bus to pass a simple object from an activity back to the main activity. Hopefully someone else can find this useful :) And if this can be improved upon please comment. Thanks.
Main Activity:
public class MainActivity extends AppCompatActivity {
Button buttonSecretMessage;
Intent intentToMessage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getInstance().register(this);
intentToMessage = new Intent(MainActivity.this, SecretMessageActivity.class);
buttonSecretMessage = (Button) findViewById(R.id.buttonSecretMessage);
buttonSecretMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(intentToMessage);
}
});
}
public MakeMySecretMessageEvent event;
#Subscribe
public void getMySecretMessage(MakeMySecretMessageEvent event) {
Toast.makeText(this, event.getMessage(), Toast.LENGTH_SHORT).show();
}
protected void onStop() {
super.onStop();
if(event != null ){
EventBus.getInstance().unregister(this);
}
}
}
SecretMessageActivity (this is where the secret message is created)
public class SecretMessageActivity extends AppCompatActivity {
Button buttonClickToMeToSeeMessage;
Intent intentToMain;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_secret_message);
intentToMain = new Intent(SecretMessageActivity.this, MainActivity.class);
buttonClickToMeToSeeMessage = (Button) findViewById(R.id.buttonClickToMeToSeeMessage);
buttonClickToMeToSeeMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MakeMySecretMessageEvent makeMySecretMessageEvent = new MakeMySecretMessageEvent();
EventBus.getInstance().post(makeMySecretMessageEvent);
startActivity(intentToMain);
}
});
}
}
MakeMySecretMessageEvent
public class MakeMySecretMessageEvent {
public MakeMySecretMessageEvent() {
}
public String getMessage() {
String message = "YOU ARE AWESOME!";
return message;
}
}
EventBus:
public final class EventBus extends Bus{
private static final EventBus Bus = new EventBus();
public static Bus getInstance() {
return Bus;
}
private EventBus() {
}
}

EventBus OnEvent() is not getting called

Hi Iam using Event bus to pass data from one fragment to another Fragment
From fragment-1 I am doing as below
#Override
public void onPause() {
bsValues = new BoreShaftValues(strtext, strtextshaft);
bus.post(bsValues);
super.onPause();
}
In Fragment-2 I registered bus in OnActivitycreated
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
bus.register(this);
}
Then I placed OnEvent() method in fragment-2
public void onEvent(BoreShaftValues event){
boregradeselect.setText(event.getBoreData());
shaftgradeselect.setText(event.getShaftData());
}
Below is my BoreshaftVales class
public class BoreShaftValues {
private String boredata;
private String shaftdata;
public BoreShaftValues(String boredata, String shaftdata){
this.boredata = boredata;
this.shaftdata = shaftdata;
}
public String getBoreData(){
return boredata;
}
public String getShaftData(){
return shaftdata;
}
}
But this OnEvent() method is not getting called at all. Am i doing it the rightway?
I typically try to tie EventBus back to the Activity and yet enable it to be loosely coupled. So in the Fragment lifecycle I register EventBus in the onAttach and unregister it in the onDetach methods in the fragment.

Categories

Resources