Search code examples
androidandroid-fragmentsandroid-asynctask

How to fix super classes have no public methods with the @Subscribe annotation in Android


I want show 3 fragments in my Activity and load data from json in any fragments! I want show each json data into one fragment, but in my application show all of data in all fragments! For example : i want show article data into article fragment, music data into music fragment and more ...
But when running application, show me this error :

FATAL EXCEPTION: main
Process: com.razemovafaghiat.tellfa.android, PID: 1865
org.greenrobot.eventbus.EventBusException: Subscriber class com.razemovafaghiat.tellfa.android.fragments.free_fragment 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 com.razemovafaghiat.tellfa.android.fragments.free_fragment.onResume(free_fragment.java:83)
  at android.support.v4.app.Fragment.performResume(Fragment.java:2020)
  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1107)
  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
  at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570)
  at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
  at android.support.v4.view.ViewPager.populate(ViewPager.java:1177)
  at android.support.v4.view.ViewPager.populate(ViewPager.java:1025)
  at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1545)
  at android.view.View.measure(View.java:17496)
  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
  at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:664)
  at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:731)
  at android.view.View.measure(View.java:17496)
  at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1075)
  at android.view.View.measure(View.java:17496)
  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
  at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
  at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
  at android.view.View.measure(View.java:17496)
  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1438)
  at android.widget.LinearLayout.measureVertical(LinearLayout.java:724)
  at android.widget.LinearLayout.onMeasure(LinearLayout.java:615)
  at android.view.View.measure(View.java:17496)
  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
  at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
  at android.view.View.measure(View.java:17496)
  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1438)
  at android.widget.LinearLayout.measureVertical(LinearLayout.java:724)
  at android.widget.LinearLayout.onMeasure(LinearLayout.java:615)
  at android.view.View.measure(View.java:17496)
  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
  at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
  at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2636)
  at android.view.View.measure(View.java:17496)
  at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2031)
  at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1193)
  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1400)
  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1078)
  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5875)
  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
  at android.view.Choreographer.doCallbacks(Choreographer.java:580)
  at android.view.Choreographer.doFrame(Choreographer.java:550)
  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
  at android.os.Handler.handleCallback(Handler.java:739)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:135)
  at android.app.ActivityThread.main(ActivityT
06-06 17:23:29.721 1865-3617/com.razemovafaghiat.tellfa.android E/error: org.json.JSONException: Index 1 out of range [0..1)
06-06 17:23:30.350 1865-3755/com.razemovafaghiat.tellfa.android E/error: org.json.JSONException: Index 1 out of range [0..1)

MyEvent code:

public class MyEvent {
    public String fragmentTag ;
    private List<DataModel> infoModels = new ArrayList<>();

    public MyEvent (String tag,List<DataModel> models){
        this.fragmentTag = tag;
        this.infoModels = models;
    }
}

freeData (AsyncTask) :

public class freeDataInfo {
    private Context mContext;
    private String ServerAddress = freeServer_IP.getFreeIP();

    public void getFreeDataInfo(Context context) {
        mContext = context;
        new getInfo().execute(ServerAddress + "limit=10");
    }

    private class getInfo extends AsyncTask<String, Void, String> {
        EventBus bus = EventBus.getDefault();
        private String ou_response;
        private List<DataModel> infoModels = new ArrayList<>();
        private ProgressDialog dialog;

        @Override
        protected void onPreExecute() {
            //CustomProcessDialog.createAndShow(mContext);

            dialog = new ProgressDialog(mContext);
            this.dialog.setMessage("شکیبا باشید...");
            this.dialog.show();
        }

        @Override
        protected String doInBackground(String... params) {
            OkHttpClient client = new OkHttpClient();

            //String url = (String) params[0];
            Request request = new Request.Builder()
                    .url(ServerAddress + "limit=10")
                    .cacheControl(CacheControl.FORCE_NETWORK)
                    .build();

            Response response;
            try {
                response = client.newCall(request).execute();
                ou_response = response.body().string();
                response.body().close();
                if (ou_response != null) {
                    try {
                        JSONObject postObj = new JSONObject(ou_response);
                        JSONArray postsArray = postObj.optJSONArray("result");

                        for (int i = 0; i <= postsArray.length(); i++) {
                            JSONObject postObject = (JSONObject) postsArray.get(i);

                            int id = postObject.getInt("id");
                            Log.d("id", String.valueOf(id));
                            String title = postObject.getString("title");
                            String description = postObject.getString("description");
                            String image = postObject.getString("image");
                            String category = postObject.getString("categoryName");
                            String date = postObject.getString("publishDate");

                            Log.d("Data", "Post ID: " + id);
                            Log.d("Data", "Post title: " + title);
                            Log.d("Data", "Post image: " + image);
                            Log.d("Data", "---------------------------------");

                            //Use the title and id as per your requirement
                            infoModels.add(new DataModel(id, title, description, category, date, image));
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                        Log.e("error", String.valueOf(e));
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("error2", String.valueOf(e));
            }
            return ou_response;
        }

        @Override
        protected void onPostExecute(String result) {
            //CustomProcessDialog.dissmis();

            //Stop Progress
            if (dialog.isShowing()) {
                dialog.dismiss();
            }

            if (result != null) {
                bus.post(new MyEvent("forfragment1", infoModels));
            } else {
                Toast.makeText(mContext, "Empty", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

paidData (AsyncTask) :

public class paidDataInfo {
    private Context mContext;
    private String ServerAddress = paidServer_IP.getPaidIP();

    public void getPaidDataInfo(Context context) {
        mContext = context;
        new getInfo().execute(ServerAddress + "limit=10");
    }

    private class getInfo extends AsyncTask<String, Void, String> {
        EventBus bus = EventBus.getDefault();
        private String ou_response;
        private List<DataModel> infoModels = new ArrayList<>();
        private ProgressDialog dialog;

        @Override
        protected void onPreExecute() {
            //CustomProcessDialog.createAndShow(mContext);
            //infoModels = new ArrayList<>();

            // Initiate Progress
            dialog = new ProgressDialog(mContext);
            this.dialog.setMessage("شکیبا باشید...");
            this.dialog.show();
        }

        @Override
        protected String doInBackground(String... params) {
            OkHttpClient client = new OkHttpClient();

            //String url = (String) params[0];
            Request request = new Request.Builder()
                    .url(ServerAddress + "limit=10")
                    .cacheControl(CacheControl.FORCE_NETWORK)
                    .build();

            Response response;
            try {
                response = client.newCall(request).execute();
                ou_response = response.body().string();
                response.body().close();
                if (ou_response != null) {
                    try {
                        JSONObject postObj = new JSONObject(ou_response);
                        JSONArray postsArray = postObj.optJSONArray("result");
                        infoModels = new ArrayList<>();

                        for (int i = 0; i <= postsArray.length(); i++) {
                            JSONObject postObject = (JSONObject) postsArray.get(i);

                            int id = postObject.getInt("id");
                            Log.d("id", String.valueOf(id));
                            String title = postObject.getString("title");
                            String description = postObject.getString("full_description");
                            String image = postObject.getString("image");
                            String category = postObject.getString("categoryName");
                            String date = postObject.getString("publishDate");

                            Log.d("Data", "Post ID: " + id);
                            Log.d("Data", "Post title: " + title);
                            Log.d("Data", "Post Desc: " + description);
                            Log.d("Data", "Post image: " + image);
                            Log.d("Data", "---------------------------------");

                            //Use the title and id as per your requirement
                            infoModels.add(new DataModel(id, title, description, category, date, image));
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                        Log.e("error", String.valueOf(e));
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("error2", String.valueOf(e));
            }
            return ou_response;
        }

        @Override
        protected void onPostExecute(String result) {
            //Stop Progress
            if (dialog.isShowing()) {
                dialog.dismiss();
            }
            //CustomProcessDialog.dissmis();
            if (result != null) {
                bus.post(new MyEvent("forfragment2", infoModels));
            } else {
                Toast.makeText(mContext, "Empty", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

free Fragment :

public class free_fragment extends Fragment {

    private RecyclerView mRecyclerView;
    private free_recycler_adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private List<DataModel> dataModels = new ArrayList<DataModel>();

    private Context context;

    @Override
    public View onCreateView(LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_free_layout, container, false);

        context = getContext();

/*        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }*/
        LoadData();

        ///----- RecyclerView -----
        mRecyclerView = (RecyclerView) view.findViewById(R.id.pdf_RecyclerView);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mAdapter = new free_recycler_adapter(context, dataModels);
        mRecyclerView.setAdapter(mAdapter);


        return view;
    }


    @Subscribe
    public void onEvent(MyEvent event, List<DataModel> mainInfoModels) {
/*        if (dataModels.size() > 0) {
            dataModels.remove(dataModels.size() - 1);
            mAdapter.notifyItemRemoved(dataModels.size());
            //mAdapter.setLoaded();
        }*/
        if (event.fragmentTag.equals("forfragment1")) {
            mAdapter.add(mainInfoModels);
            mAdapter.notifyDataSetChanged();
        }
    }

    private void LoadData() {
        freeDataInfo dataInfo = new freeDataInfo();
        // here getMainDataInfo() should return the server response
        dataInfo.getFreeDataInfo(context);
    }

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

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

paid fragment :

public class paid_fragment extends Fragment {

    private RecyclerView mRecyclerView;
    private paid_recycler_adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private List<DataModel> dataModels = new ArrayList<DataModel>();

    private Context context;

    @Override
    public View onCreateView(LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_paid_layout, container, false);

        context = getContext();

/*        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }*/

        LoadData();

        ///----- RecyclerView -----
        mRecyclerView = (RecyclerView) view.findViewById(R.id.voice_RecyclerView);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mAdapter = new paid_recycler_adapter(context, dataModels);
        mRecyclerView.setAdapter(mAdapter);

        return view;
    }

    @Subscribe
    public void onEvent(MyEvent event, List<DataModel> mainInfoModels) {
/*        if (dataModels.size() > 0) {
            dataModels.remove(dataModels.size() - 1);
            mAdapter.notifyItemRemoved(dataModels.size());
            //mAdapter.setLoaded();
        }*/

        if (event.fragmentTag.equals("forfragment2")) {
            mAdapter.add(mainInfoModels);
            mAdapter.notifyDataSetChanged();
        }
    }

    private void LoadData() {
        paidDataInfo dataInfo = new paidDataInfo();
        // here getMainDataInfo() should return the server response
        dataInfo.getPaidDataInfo(context);
    }

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

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

How can i fix this problem? Thanks all <3


Solution

  • remove the list parameter from you onEvent method. instead use the List you already put into the event. that would either require to make the field public in your event or add a getter for the list.

    something like this:

    public class MyEvent {
        public String fragmentTag ;
        private List<DataModel> infoModels = new ArrayList();
    
        public MyEvent (String tag,List<DataModel> models){
            this.fragmentTag = tag;
            this.infoModels = models;
        }
    
        public List<DataModel> getInfoModels() {
            return infoModels;
        }
    }
    
     @Subscribe
        public void onEvent(MyEvent event) {
           List<DataModel> dataModels = event.getInfoModels();
           if (dataModels.size() > 0) {
                dataModels.remove(dataModels.size() - 1);
                mAdapter.notifyItemRemoved(dataModels.size());
                //mAdapter.setLoaded();
            }
    
            if (event.fragmentTag.equals("forfragment2")) {
                mAdapter.add(mainInfoModels);
                mAdapter.notifyDataSetChanged();
            }
        }