【问题标题】:How to fix super classes have no public methods with the @Subscribe annotation in Android如何修复超类在Android中没有带有@Subscribe注解的公共方法
【发布时间】:2016-06-07 06:21:10
【问题描述】:

我想在我的Activity 中显示 3 fragments 并从任何fragments 中的 json 加载数据!我想将每个 json 数据显示到一个片段中,但在我的应用程序中显示所有片段中的所有数据! 例如:我想将文章数据显示为文章片段,将音乐数据显示为音乐片段等等...
但是在运行应用程序时,显示此错误:

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)

我的活动代码:

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(异步任务):

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();
            }
        }
    }
}

免费片段:

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();
    }
}

付费片段:

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();
    }
}

我该如何解决这个问题?谢谢大家

【问题讨论】:

  • 检查您是否导入了正确的@Subscribe 注释。也许您的类路径中有多个并导入了错误的。
  • 更正:您的 on Event 有两个参数。它应该只有 event 参数。不是列表。
  • @Dodge,你能把代码发给我吗?请
  • 事件总线是用来触发事件的,不是用来发送数据的。从onEvent参数中去掉列表
  • @Mohammad 我添加了一个示例。其他 sn-ps 你必须自己更新。

标签: android android-fragments android-asynctask


【解决方案1】:

如果您在构建中使用 proguard。确保这些行在您的 android.proguard 配置文件中。 (也适用于 Flutter 项目)

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

【讨论】:

    【解决方案2】:

    我遇到了同样的错误,经过一段时间的挖掘,我发现问题是由于错误的导入

    我用过 导入 com.google.common.eventbus.Subscribe;

    而不是 导入 org.greenrobot.eventbus.Subscribe;

    希望这对外面的人有帮助。

    【讨论】:

      【解决方案3】:

      onEvent 方法中删除列表参数。而是使用您已经放入事件的列表。这要么需要在您的事件中公开该字段,要么为列表添加一个 getter。

      类似这样的:

      公共类 MyEvent { 公共字符串片段标签; 私有列表 infoModels = new ArrayList(); public MyEvent (String tag,List 模型){ this.fragmentTag = 标签; this.infoModels = 模型; } 公共列表 getInfoModels() { 返回信息模型; } } @订阅 公共无效onEvent(MyEvent事件){ List dataModels = event.getInfoModels(); if (dataModels.size() > 0) { dataModels.remove(dataModels.size() - 1); mAdapter.notifyItemRemoved(dataModels.size()); //mAdapter.setLoaded(); } 如果(event.fragmentTag.equals(“forfragment2”)){ mAdapter.add(mainInfoModels); mAdapter.notifyDataSetChanged(); } }

      【讨论】:

      • 我应该在这个片段上显示任何片段数据。但是当使用默认的 EventBus 代码时,会显示所有片段中的任何片段!
      • 谢谢你,但是public ListgetInfoModels() { return infoModels; } 显示错误!请查看此图片是否有错误:imgur.com/kwAVUoZ
      • 请帮帮我,我真的需要这个
      • 我修好了这条线。 stackoverflow 确实破坏了 东西
      • 谢谢我亲爱的朋友
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 2011-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多