web-dev-qa-db-fra.com

EventBus - La classe abonné et ses super-classes n'ont aucune méthode publique avec l'annotation @subscribe

Je crée une application Android à l'aide d'EventBus pour la publication d'émissions asynchrones vers d'autres classes, mais je rencontre une erreur lors de l'exécution.

MainActivity.Java

import Android.content.Intent;
import Android.support.v7.app.AppCompatActivity;
import Android.os.Bundle;
import Android.view.View;
import Android.widget.Button;
import Android.widget.EditText;
import com.google.Android.gms.maps.model.LatLng;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;


public class MainActivity extends AppCompatActivity {

    //Globals
    public String uname = null;
    public double lat = 0;
    public double lng = 0;

    //Get GUI handles
    public Button sendButton; //
    public EditText username;
    public Button MapButton; //
    public EditText LatBox;
    public EditText LngBox;


    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        //register EventBus
        EventBus.getDefault().register(this);

        super.onCreate(savedInstanceState);
        //set GUI for MainActivity
        setContentView(R.layout.activity_main);

        //get handlers
        LatBox = (EditText)findViewById(R.id.LatBox);
        LngBox = (EditText)findViewById(R.id.LngBox);

        MapButton = (Button)findViewById(R.id.locationButton);
        //Call the class which will handle finding coordinates
        MapButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent MapIntent = new Intent(getApplicationContext(), MapClass.class);
                startActivityForResult(MapIntent, 0);
            }
        });

        sendButton = (Button)findViewById(R.id.Submit);
        //Set action for Button
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //Get username from user
                username  = (EditText)findViewById(R.id.UsernameText);
                uname = username.getText().toString();

                //Generate intent to start IntentService
                Intent i = new Intent(getApplicationContext(), Register.class);

                //Put the extra field of username
                i.putExtra("username", uname);
                i.putExtra("latitude", lat);
                i.putExtra("longitude", lng);
                i.putExtra("type", "meetup.be2015.gcm_meetup.MAIN_ACTIVITY");

                //Start the IntentService on a different thread
                startService(i);
            }
        });

    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(LatLng currentPos){

        LatBox.setText(String.valueOf(currentPos.latitude));
        LngBox.setText(String.valueOf(currentPos.longitude));

        lat = currentPos.latitude;
        lng = currentPos.longitude;
    }
}

MapClass.Java

import Android.app.IntentService;
import Android.content.Intent;
import Android.location.Location;
import Android.net.Uri;
import Android.os.Bundle;
import Android.support.v7.app.AppCompatActivity;
import Android.util.Log;
import com.google.Android.gms.appindexing.Action;
import com.google.Android.gms.appindexing.AppIndex;
import com.google.Android.gms.common.ConnectionResult;
import com.google.Android.gms.common.api.GoogleApiClient;
import com.google.Android.gms.location.LocationServices;
import com.google.Android.gms.maps.GoogleMap;
import com.google.Android.gms.maps.OnMapReadyCallback;
import com.google.Android.gms.maps.model.LatLng;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

public class MapClass extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private GoogleApiClient mGoogleApiClient;
    private GoogleMap mgoogleMap;
    private LatLng latLng;
    private GoogleApiClient client;

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mgoogleMap = googleMap;
        mgoogleMap.setMyLocationEnabled(true);      //Sets location to current position
        buildGoogleApiClient();
        mGoogleApiClient.connect();
    }

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

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

    @Override
    public void onConnected(Bundle bundle) {
        Location MLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if (MLastLocation != null) {
            latLng = new LatLng(MLastLocation.getLatitude(), MLastLocation.getLongitude());

            //Post the LatLng to MainActivity
            EventBus.getDefault().post(latLng);

            //Send sticky event to Register and MyGcmListenerService
            EventBus.getDefault().postSticky(latLng);

        } else {
            Log.d("onConnected", "Value of LatLng is NULL");
            latLng = new LatLng(0, 0);   //equator
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        //Notify
        Log.d("ConnectionSuspended", "Connection Suspended. Status: " +   i);
        mgoogleMap.clear();
        mGoogleApiClient.disconnect();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        //Notify
        Log.d("ConnectionFailed", "Connection Failed. Status: " + connectionResult.toString());
        mgoogleMap.clear();
        mGoogleApiClient.disconnect();
    }

    @Subscribe
    public void onEvent() {
        Log.d("EVENT", "EVENT");
    }

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


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

    }
}

Le LogCat montre ce qui suit:

03-08 22:54:56.970 8570-8570/meetup.be2015.gcm_meetup E/AndroidRuntime: FATAL EXCEPTION: main
Java.lang.RuntimeException: Unable to start activity ComponentInfo{meetup.be2015.gcm_meetup/meetup.be2015.gcm_meetup.MapClass}:
org.greenrobot.eventbus.EventBusException: Subscriber class meetup.be2015.gcm_meetup.MapClass 
and its super classes have no public methods with the @Subscribe annotation
at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2118)
at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2143)
at Android.app.ActivityThread.access$700(ActivityThread.Java:140)
at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1237)
at Android.os.Handler.dispatchMessage(Handler.Java:99)
at Android.os.Looper.loop(Looper.Java:174)
at Android.app.ActivityThread.main(ActivityThread.Java:4952)
at Java.lang.reflect.Method.invokeNative(Native Method)
at Java.lang.reflect.Method.invoke(Method.Java:511)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1027)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:794)
at dalvik.system.NativeStart.main(Native Method)
Caused by: org.greenrobot.eventbus.EventBusException: Subscriber class meetup.be2015.gcm_meetup.MapClass 
and its super classes have no public methods with the @Subscribe annotation
at org.greenrobot.eventbus.SubscriberMethodFinder.findSubscriberMethods(SubscriberMethodFinder.Java:67)
at org.greenrobot.eventbus.EventBus.register(EventBus.Java:136)
at meetup.be2015.gcm_meetup.MapClass.onStart(MapClass.Java:91)
at Android.app.Instrumentation.callActivityOnStart(Instrumentation.Java:1178)
at Android.app.Activity.performStart(Activity.Java:5198)
at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2091)
at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2143) 
at Android.app.ActivityThread.access$700(ActivityThread.Java:140) 
at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1237) 
at Android.os.Handler.dispatchMessage(Handler.Java:99) 
at Android.os.Looper.loop(Looper.Java:174) 
at Android.app.ActivityThread.main(ActivityThread.Java:4952) 
at Java.lang.reflect.Method.invokeNative(Native Method) 
at Java.lang.reflect.Method.invoke(Method.Java:511) 
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1027) 
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:794) 
at dalvik.system.NativeStart.main(Native Method) 

Pourquoi cela arrive-t-il? Est-ce que je fais quelque chose de mal?

18
Rahul Kulhalli

je pense que c'est parce que onEvent à l'intérieur de MapClass.Java n'a pas de paramètre. Pourriez-vous essayer avec le paramètre attendu?

12
elsennov

Assurez-vous que ces lignes figurent dans votre fichier de configuration de proguard si vous utilisez proguard pour vos versions.

-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
81
Lavakush

J'ai fait face au même problème et après une longue recherche, j'ai trouvé la solution pour chaque cas. Ce problème est dû à l'absence de la méthode publique @Subscribe onEvent () dans la classe pour laquelle vous essayez d'enregistrer le bus d'événements sous le nom de EventBus.getDefault().register(this). La présence de cette fonction est obligatoire si vous enregistrez une classe avec Event Bus.

Cela peut être dans deux situations

  1. using progruad: progruad peut modifier le nom de la méthode onEvent () car le bus d’événements n’est pas en mesure de le trouver . Mettez ces lignes dans vos règles de programme 

    -keepattributes Annotation

    classe des membres de la classe de gardiens ** {

    @ org.greenrobot.eventbus.Subscribe;

    }

    -keep enum org.greenrobot.eventbus.ThreadMode {*; 

}

  1. si vous n'utilisez pas progruard, alors il est certain que votre classe manque de la méthode onEvent () avec l'annotation @Subscribe. Cette annotation avec méthode est obligatoire avec EventBus version 3.0.0. Vérifiez donc bien la présence de cette méthode dans votre classe.
5
saksham

Dans ma situation, j'ai eu cette erreur car je n'ai pas écrit @Subscribe sur la classe où je suis inscrit à EventBus.

4
Allen Vork

Juste au cas où votre code est comme le mien: p

J'ai dû définir la méthode sur public car c'est actuellement private

3
Woppi

Dans mon cas, onEvent() était private et placé dans child class .

Mais register() et unregister() ont été appelés dans classe parent .

La solution consistait à rendre onEvent() public .

1
Johnny Five

Juste au cas où cela aiderait quelqu'un, dans mon cas, j'ai oublié de passer des arguments à la méthode de réception, tout le reste allait bien. Quand aucun argument n'est passé à la fonction/méthode réceptrice, dans ce cas, cette exception est levée.

0
Wajid Ali

Sur un sidenote, j'ai eu la même erreur après être passé de l'implémentation de Google de l'EventBus à celui-ci. Cette erreur m'a rendu fou, car l'EventBus de Google a également une annotation @Subscribe et j'utilisais celle-ci au lieu de celle fournie par greenrobot. 

 enter image description here

OK, c'est une erreur très stupide de ma part, mais si je peux aider même une personne comme moi, je suis heureux. 

0
rTECH